here we go... updating shadows/org.eclipse.jdt.core in HEAD with the latest jdt compiler version (v_552a)
diff --git a/org.eclipse.jdt.core/.cvsignore b/org.eclipse.jdt.core/.cvsignore
new file mode 100644
index 0000000..da63a8f
--- /dev/null
+++ b/org.eclipse.jdt.core/.cvsignore
@@ -0,0 +1,2 @@
+bin
+antbin
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/.options b/org.eclipse.jdt.core/.options
index 0daf859..04438d0 100644
--- a/org.eclipse.jdt.core/.options
+++ b/org.eclipse.jdt.core/.options
@@ -42,4 +42,22 @@
 org.eclipse.jdt.core/debug/selection=false

 

 # Reports access to zip and jar files through the Java model

-org.eclipse.jdt.core/debug/zipaccess=false
\ No newline at end of file
+org.eclipse.jdt.core/debug/zipaccess=false

+

+# Reports the time to perform code completion.

+org.eclipse.jdt.core/perf/completion=300

+

+# Reports the time to perform code selection.

+org.eclipse.jdt.core/perf/selection=300

+

+# Reports the time to process a java element delta.

+org.eclipse.jdt.core/perf/javadeltalistener=500

+

+# Reports the time to perform an initialization of a classpath variable.

+org.eclipse.jdt.core/perf/variableinitializer=5000

+

+# Reports the time to perform an initialization of a classpath container.

+org.eclipse.jdt.core/perf/containerinitializer=5000

+

+# Reports the time to perform a reconcile operation.

+org.eclipse.jdt.core/perf/reconcile=1000
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
index 4bcd4d1..296ef11 100644
--- a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
@@ -1,65 +1,65 @@
-#Fri Sep 03 12:55:26 CEST 2004
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
-org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
-org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
-org.eclipse.jdt.core.compiler.problem.unusedImport=warning
-org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
-org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+#Fri Apr 15 23:54:42 CEST 2005
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
 org.eclipse.jdt.core.builder.invalidClasspath=abort
 org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
-org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
-org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.problem.deprecation=warning
-org.eclipse.jdt.core.compiler.source=1.3
-org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
-org.eclipse.jdt.core.compiler.compliance=1.4
-org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
-org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
-org.eclipse.jdt.core.builder.cleanOutputFolder=clean
-org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
-org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
-org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
-org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
-org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
-org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
-org.eclipse.jdt.core.incompatibleJDKLevel=ignore
-eclipse.preferences.version=1
 org.eclipse.jdt.core.circularClasspath=error
-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
-org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
-org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
-org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
 org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
-org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.doc.comment.support=enabled
-org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
-org.eclipse.jdt.core.incompleteClasspath=error
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
 org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
 org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
-org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
 org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
\ No newline at end of file
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/org.eclipse.jdt.core/about.html b/org.eclipse.jdt.core/about.html
index 7e14392..293fb80 100644
--- a/org.eclipse.jdt.core/about.html
+++ b/org.eclipse.jdt.core/about.html
@@ -1,30 +1,22 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
 <html>
 <head>
-<title>About</title>
 <meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+<title>About</title>
 </head>
 <body lang="EN-US">
 <h2>About This Content</h2>
 
-<p>20th June, 2002</p>	
+<p>February 24, 2005</p>	
 <h3>License</h3>
-<p>Eclipse.org makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
-Common Public License Version 1.0 (&quot;CPL&quot;).  A copy of the CPL is available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
-For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
 
-<h3>Contributions</h3>
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;).  A copy of the EPL is available at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
 
-<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
-made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
-Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
-
-<p>If this Content is licensed to you under license terms and conditions other than the CPL (&quot;Other License&quot;), any modifications, enhancements and/or
-other code and/or documentation (&quot;Modifications&quot;) uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
-host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
-to others under the terms of the Other License.  In addition, with regard to Modifications for which you are the copyright holder, you are also
-providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
-the CPL.</p>
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content.</p>
 
 <h3>Disassembler</h3>
 <p>This plug-in contains a bytecode disassembler (&quot;Disassembler&quot;) that can produce a listing of the Java assembler mnemonics (&quot;Assembler Mnemonics&quot;) for a Java method.  If you 
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
index 2eb335b..6e2eb55 100644
--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/CheckDebugAttributes.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -22,7 +22,21 @@
 import org.eclipse.jdt.core.util.IMethodInfo;
 import org.eclipse.jdt.internal.antadapter.AntAdapterMessages;
 
-public class CheckDebugAttributes extends Task {
+/**
+ * <p>An Ant task to find out if a class file or a jar contains debug attributes. If this is the case,
+ * the property contains the value "has debug" after the call.
+ * </p> 
+ * <p>
+ * <code>&lt;eclipse.checkDebugAttributes property="hasDebug" file="${basedir}/bin/p/A.class"/&gt;</code>
+ * </p>
+ * <p>
+ * For more information on Ant check out the website at http://jakarta.apache.org/ant/ .
+ * </p>
+ * 
+ * This is not intended to be subclassed by users.
+ * @since 2.0
+ */
+public final class CheckDebugAttributes extends Task {
 
 	private String file;
 	private String property;
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
index ea751ba..2edf25f 100644
--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
index 2c7697b..79903d3 100644
--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -51,4 +51,4 @@
 			return '!' + key + '!';
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties
index 781388a..bf95bd3 100644
--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/internal/antadapter/messages.properties
@@ -1,10 +1,10 @@
 ###############################################################################
 # Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
@@ -21,4 +21,4 @@
 checkDebugAttributes.file.argument.cannot.be.null=The file argument cannot be null
 checkDebugAttributes.property.argument.cannot.be.null=The property argument cannot be null
 checkDebugAttributes.ioexception.occured=IOException occured while reading 
-checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile=The file argument must be a .class or a .jar file
\ No newline at end of file
+checkDebugAttributes.file.argument.must.be.a.classfile.or.a.jarfile=The file argument must be a .class or a .jar file
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
index 707a9db..59a97fd 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
index 6bc60be..56b037a 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java
index fea1e7d..09de7ba 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
index 4f34070..7293c7f 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileFinder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
index 82489f3..a98b0e7 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index d3ad3c8..19ed7a8 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,6 +12,7 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FilenameFilter;
 import java.io.IOException;
@@ -20,12 +21,18 @@
 import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Locale;
 import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
@@ -44,6 +51,7 @@
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 import org.eclipse.jdt.internal.compiler.util.Util;
@@ -51,26 +59,236 @@
 public class Main implements ProblemSeverities, SuffixConstants {
 
 	public static class Logger {
-		
-		PrintWriter out;
-		PrintWriter err;
-		PrintWriter log;
-		
+		private static final String CLASS = "class"; //$NON-NLS-1$
+		private static final String CLASS_FILE = "classfile"; //$NON-NLS-1$
+		private static final String CLASSPATH = "classpath"; //$NON-NLS-1$
+		private static final String CLASSPATH_ID = "id"; //$NON-NLS-1$
+		private static final String CLASSPATH_FILE = "FILE"; //$NON-NLS-1$
+		private static final String CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$
+		private static final String CLASSPATH_JAR = "JAR"; //$NON-NLS-1$
+		private static final String CLASSPATHS = "classpaths"; //$NON-NLS-1$
+		private static final String COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$
+		private static final String COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$
+		private static final String COMPILER = "compiler"; //$NON-NLS-1$
+		private static final String COMPILER_COPYRIGHT = "copyright"; //$NON-NLS-1$
+		private static final String COMPILER_VERSION = "version"; //$NON-NLS-1$
+		private static final String COMPILER_NAME = "name"; //$NON-NLS-1$
+		private static final String EXCEPTION = "exception"; //$NON-NLS-1$
+		private static final String ERROR = "ERROR"; //$NON-NLS-1$
+		private static final String ERROR_TAG = "error"; //$NON-NLS-1$
+		private static final String KEY = "key"; //$NON-NLS-1$
+		private static final String MESSAGE = "message"; //$NON-NLS-1$
+		private static final String NUMBER_OF_CLASSFILES = "number_of_classfiles"; //$NON-NLS-1$
+		private static final String NUMBER_OF_ERRORS = "errors"; //$NON-NLS-1$
+		private static final String NUMBER_OF_LINES = "number_of_lines"; //$NON-NLS-1$
+		private static final String NUMBER_OF_PROBLEMS = "problems"; //$NON-NLS-1$
+		private static final String NUMBER_OF_TASKS = "tasks"; //$NON-NLS-1$
+		private static final String NUMBER_OF_WARNINGS = "warnings"; //$NON-NLS-1$
+		private static final String OPTION = "option"; //$NON-NLS-1$
+		private static final String OPTIONS = "options"; //$NON-NLS-1$
+		private static final String PATH = "path"; //$NON-NLS-1$
+		private static final String PROBLEM_ARGUMENT = "argument"; //$NON-NLS-1$
+		private static final String PROBLEM_ARGUMENT_VALUE = "value"; //$NON-NLS-1$
+		private static final String PROBLEM_ARGUMENTS = "arguments"; //$NON-NLS-1$
+		private static final String PROBLEM_ID = "id"; //$NON-NLS-1$
+		private static final String PROBLEM_LINE = "line"; //$NON-NLS-1$
+		private static final String PROBLEM_MESSAGE = "message"; //$NON-NLS-1$
+		private static final String PROBLEM_SEVERITY = "severity"; //$NON-NLS-1$
+		private static final String PROBLEM_SOURCE_START = "charStart"; //$NON-NLS-1$
+		private static final String PROBLEM_SOURCE_END = "charEnd"; //$NON-NLS-1$
+		private static final String PROBLEM_SUMMARY = "problem_summary"; //$NON-NLS-1$
+		private static final String PROBLEM_TAG = "problem"; //$NON-NLS-1$
+		private static final String PROBLEMS = "problems"; //$NON-NLS-1$
+		private static final String SOURCE = "source"; //$NON-NLS-1$
+		private static final String SOURCE_CONTEXT = "source_context"; //$NON-NLS-1$
+		private static final String SOURCE_END = "sourceEnd"; //$NON-NLS-1$
+		private static final String SOURCE_START = "sourceStart"; //$NON-NLS-1$
+		private static final String SOURCES = "sources"; //$NON-NLS-1$
+		private static final String STATS = "stats"; //$NON-NLS-1$
+		private static final String TASK = "task"; //$NON-NLS-1$
+		private static final String TASKS = "tasks"; //$NON-NLS-1$
+		private static final String TIME = "time"; //$NON-NLS-1$
+		private static final String VALUE = "value"; //$NON-NLS-1$
+		private static final String WARNING = "WARNING"; //$NON-NLS-1$
+		private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$
+		private static final String XML_DTD_DECLARATION = "<!DOCTYPE compiler SYSTEM \"compiler.dtd\">"; //$NON-NLS-1$
+
+		private static final HashMap FIELD_TABLE = new HashMap();
+		static {
+			try {
+				Class c = IProblem.class;
+				Field[] fields = c.getFields();
+				for (int i = 0, max = fields.length; i < max; i++) {
+					Field field = fields[i];
+					FIELD_TABLE.put(field.get(null), field.getName());
+				}
+			} catch (SecurityException e) {
+				e.printStackTrace();
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+		private static void appendEscapedChar(StringBuffer buffer, char c) {
+			String replacement= getReplacement(c);
+			if (replacement != null) {
+				buffer.append('&');
+				buffer.append(replacement);
+				buffer.append(';');
+			} else {
+				buffer.append(c);
+			}
+		}
+		private static String getEscaped(String s) {
+			StringBuffer result= new StringBuffer(s.length() + 10);
+			for (int i= 0; i < s.length(); ++i)
+				appendEscapedChar(result, s.charAt(i));
+			return result.toString();
+		}
+		private static String getReplacement(char c) {
+			// Encode special XML characters into the equivalent character references.
+			// These five are defined by default for all XML documents.
+			switch (c) {
+				case '<' :
+					return "lt"; //$NON-NLS-1$
+				case '>' :
+					return "gt"; //$NON-NLS-1$
+				case '"' :
+					return "quot"; //$NON-NLS-1$
+				case '\'' :
+					return "apos"; //$NON-NLS-1$
+				case '&' :
+					return "amp"; //$NON-NLS-1$
+			}
+			return null;
+		}
+		private PrintWriter err;
+		boolean isXml;
+		private PrintWriter log;
+		private PrintWriter out;
+		private int tab;
+		private HashMap parameters;
+
 		public Logger(PrintWriter out, PrintWriter err) {
 			this.out = out;
 			this.err = err;
+			this.isXml = false;
+			this.parameters = new HashMap();
 		}
-		
-		public void setLog(PrintWriter log) {
-			this.log = log;
+
+		public String buildFileName(
+			String outputPath,
+			String relativeFileName) {
+			char fileSeparatorChar = File.separatorChar;
+			String fileSeparator = File.separator;
+			
+			outputPath = outputPath.replace('/', fileSeparatorChar);
+			// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+			StringBuffer outDir = new StringBuffer(outputPath);
+			if (!outputPath.endsWith(fileSeparator)) {
+				outDir.append(fileSeparator);
+			}
+			StringTokenizer tokenizer =
+				new StringTokenizer(relativeFileName, fileSeparator);
+			String token = tokenizer.nextToken();
+			while (tokenizer.hasMoreTokens()) {
+				outDir.append(token).append(fileSeparator);
+				token = tokenizer.nextToken();
+			}
+			// token contains the last one
+			return outDir.append(token).toString();
 		}
 		
 		public void close() {
 			if (this.log != null) {
+				if (this.isXml) {
+					this.endTag(COMPILER);
+					this.flush();
+				}
 				this.log.close();
 			}
 		}
+
+		/**
+		 * 
+		 */
+		public void compiling() {
+			this.printlnOut(Main.bind("progress.compiling")); //$NON-NLS-1$
+		}
 		
+		/**
+		 * Used to stop logging problems.
+		 * Only use in xml mode.
+		 */
+		private void endLoggingProblems() {
+			this.endTag(PROBLEMS);
+		}
+		public void endLoggingSource() {
+			if (this.isXml) {
+				this.endTag(SOURCE);
+			}
+		}
+		public void endLoggingSources() {
+			if (this.isXml) {
+				this.endTag(SOURCES);
+			}
+		}
+		public void endLoggingTasks() {
+			if (this.isXml) {
+				this.endTag(TASKS);
+			}
+		}
+		public void endTag(String name) {
+			tab--;
+			this.printTag('/' + name, null, true, false);
+			this.tab--;
+		}
+		
+		private void extractContext(IProblem problem, char[] unitSource) {
+			//sanity .....
+			int startPosition = problem.getSourceStart();
+			int endPosition = problem.getSourceEnd();
+			if ((startPosition > endPosition)
+				|| ((startPosition < 0) && (endPosition < 0))) {
+				this.parameters.put(VALUE, Messages.problem_noSourceInformation); 
+				this.parameters.put(SOURCE_START, "-1"); //$NON-NLS-1$
+				this.parameters.put(SOURCE_END, "-1"); //$NON-NLS-1$
+				return;
+			}
+
+			char c;
+			//the next code tries to underline the token.....
+			//it assumes (for a good display) that token source does not
+			//contain any \r \n. This is false on statements ! 
+			//(the code still works but the display is not optimal !)
+
+			// expand to line limits
+			int length = unitSource.length, begin, end;
+			for (begin = startPosition >= length ? length - 1 : startPosition; begin > 0; begin--) {
+				if ((c = unitSource[begin - 1]) == '\n' || c == '\r') break;
+			}
+			for (end = endPosition >= length ? length - 1 : endPosition ; end+1 < length; end++) {
+				if ((c = unitSource[end + 1]) == '\r' || c == '\n') break;
+			}
+
+			// trim left and right spaces/tabs
+			while ((c = unitSource[begin]) == ' ' || c == '\t') begin++;
+			while ((c = unitSource[end]) == ' ' || c == '\t') end--;
+			
+			// copy source
+			StringBuffer buffer = new StringBuffer();
+			buffer.append(unitSource, begin, end - begin + 1);
+			
+			this.parameters.put(VALUE, String.valueOf(buffer)); //$NON-NLS-1$
+			this.parameters.put(SOURCE_START, Integer.toString(startPosition - begin)); //$NON-NLS-1$
+			this.parameters.put(SOURCE_END, Integer.toString(endPosition - begin)); //$NON-NLS-1$
+		}
+
+		private String getFieldName(int id) {
+			return (String) FIELD_TABLE.get(new Integer(id));
+		}
+
 		public void flush() {
 			this.out.flush();
 			this.err.flush();
@@ -78,32 +296,625 @@
 				this.log.flush();
 			}
 		}
+		public void logAverage(long[] times, long lineCount) {
+			Arrays.sort(times);
+			final int length = times.length;
+			long sum = 0;
+			for (int i = 1, max = length - 1; i < max; i++) {
+				sum += times[i];
+			}
+			long time = sum / (length - 2);
+			this.printlnOut(Main.bind(
+				"compile.averageTime", //$NON-NLS-1$
+				new String[] {
+					String.valueOf(lineCount),
+					String.valueOf(time),
+					String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0) }));
+		}
+		public void logClasspath(String[] classpaths) {
+			if (classpaths == null) return;
+			if (this.isXml) {
+				final int length = classpaths.length;
+				if (length != 0) {
+					// generate xml output
+					this.printTag(CLASSPATHS, null, true, false);
+					for (int i = 0; i < length; i++) {
+						this.parameters.clear();
+						String classpath = classpaths[i];
+						parameters.put(PATH, classpath);
+						File f = new File(classpath);
+						String id = null;
+						if (f.isFile()) {
+							if (Util.isArchiveFileName(classpath)) {
+								id = CLASSPATH_JAR;
+							} else {
+								id = CLASSPATH_FILE;
+							}
+						} else if (f.isDirectory()) {
+							id = CLASSPATH_FOLDER;
+						}
+						if (id != null) {
+							this.parameters.put(CLASSPATH_ID, id);
+							this.printTag(CLASSPATH, parameters, true, true);
+						}
+					}
+					this.endTag(CLASSPATHS);
+				}
+			}
+			
+		}
+
+		public void logClassFile(boolean generatePackagesStructure, String outputPath, String relativeFileName) {
+			if (this.isXml) {
+				String fileName = null;
+				if (generatePackagesStructure) {
+					fileName = buildFileName(outputPath, relativeFileName);
+				} else {
+					char fileSeparatorChar = File.separatorChar;
+					String fileSeparator = File.separator;
+					// First we ensure that the outputPath exists
+					outputPath = outputPath.replace('/', fileSeparatorChar);
+					// To be able to pass the mkdirs() method we need to remove the extra file separator at the end of the outDir name
+					int indexOfPackageSeparator = relativeFileName.lastIndexOf(fileSeparatorChar);
+					if (indexOfPackageSeparator == -1) {
+						if (outputPath.endsWith(fileSeparator)) {
+							fileName = outputPath + relativeFileName;
+						} else {
+							fileName = outputPath + fileSeparator + relativeFileName;
+						}
+					} else {
+						int length = relativeFileName.length();
+						if (outputPath.endsWith(fileSeparator)) {
+							fileName = outputPath + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+						} else {
+							fileName = outputPath + fileSeparator + relativeFileName.substring(indexOfPackageSeparator + 1, length);
+						}
+					}
+				}
+				File f = new File(fileName);
+				try {
+					this.parameters.clear();
+					this.parameters.put(PATH, f.getCanonicalPath());
+					this.printTag(CLASS_FILE, this.parameters, true, true);
+				} catch (IOException e) {
+					this.logNoClassFileCreated(fileName);
+				}
+			}			
+		}
 		
-		public void printErr(String s) {
+		public void logCommandLineArguments(String[] commandLineArguments) {
+			if (commandLineArguments == null) return;
+			if (this.isXml) {
+				final int length = commandLineArguments.length;
+				if (length != 0) {
+					// generate xml output
+					this.printTag(COMMAND_LINE_ARGUMENTS, null, true, false);
+					parameters.clear();
+					for (int i = 0; i < length; i++) {
+						parameters.put(VALUE, commandLineArguments[i]);
+						this.printTag(COMMAND_LINE_ARGUMENT, parameters, true, true);
+					}
+					this.endTag(COMMAND_LINE_ARGUMENTS);
+				}
+			}
+		}
+
+		/**
+		 * @param e the given exception to log
+		 */
+		public void logException(Exception e) {
+			final String message = e.getMessage();
+			if (isXml) {
+				parameters.clear();
+				parameters.put(MESSAGE, message);
+				parameters.put(CLASS, e.getClass());
+				this.printTag(EXCEPTION, parameters, true, true);
+			}
+			this.printlnErr(message);
+		}
+
+		/**
+		 * @param wrongClasspath
+		 *            the given wrong classpath entry
+		 */
+		public void logIncorrectClasspath(String wrongClasspath) {
+			if (isXml) {
+				this.parameters.clear();
+				this.parameters.put(MESSAGE, Main.bind("configure.incorrectClasspath", wrongClasspath)); //$NON-NLS-1$
+				this.printTag(ERROR_TAG, this.parameters, true, true);
+			}
+			this.printlnErr(Main.bind(
+				"configure.incorrectClasspath", wrongClasspath)); //$NON-NLS-1$
+		}
+
+		/**
+		 * 
+		 */
+		public void logNoClassFileCreated(String fileName) {
+			if (isXml) {
+				this.parameters.clear();
+				this.parameters.put(MESSAGE, Main.bind("output.noClassFileCreated", fileName)); //$NON-NLS-1$
+				this.printTag(ERROR_TAG, this.parameters, true, true);
+			}
+			this.printlnErr(Main.bind("output.noClassFileCreated", fileName)); //$NON-NLS-1$
+		}
+
+		public void logNoClasspath() {
+			if (isXml) {
+				this.parameters.clear();
+				this.parameters.put(MESSAGE, Main.bind("configure.noClasspath")); //$NON-NLS-1$//$NON-NLS-2$
+				this.printTag(ERROR_TAG, this.parameters, true, true);
+			}
+			this.printlnErr(Main.bind("configure.noClasspath")); //$NON-NLS-1$
+		}
+
+		/**
+		 * @param exportedClassFilesCounter
+		 */
+		public void logNumberOfClassFilesGenerated(int exportedClassFilesCounter) {
+			if (isXml) {
+				this.parameters.clear();
+				this.parameters.put(VALUE, new Integer(exportedClassFilesCounter)); //$NON-NLS-1$
+				this.printTag(NUMBER_OF_CLASSFILES, this.parameters, true, true);
+			}
+			if (exportedClassFilesCounter == 1) {
+				this.printlnOut(Main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
+			} else {
+				this.printlnOut(Main.bind("compile.severalClassFilesGenerated", //$NON-NLS-1$
+					String.valueOf(exportedClassFilesCounter)));
+			}
+		}
+
+		/**
+		 * @param options the given compiler options
+		 */
+		public void logOptions(Map options) {
+			if (this.isXml) {
+				this.printTag(OPTIONS, null, true, false);
+				final Set keySet = options.keySet();
+				Object[] keys = keySet.toArray();
+				Arrays.sort(keys);
+				for (int i = 0, max = keys.length; i < max; i++) {
+					this.parameters.clear();
+					Object key = keys[i];
+					this.parameters.put(KEY, key);
+					this.parameters.put(VALUE, options.get(key));
+					this.printTag(OPTION, this.parameters, true, true);
+				}
+				this.endTag(OPTIONS);
+			}
+		}
+
+		private void logProblem(IProblem problem, int localErrorCount,
+			int globalErrorCount, char[] unitSource) {
+			if (localErrorCount == 0) {
+				this.printlnErr("----------"); //$NON-NLS-1$
+			}
+			this.printlnErr(problem.isError() ?
+				Main.bind(
+					"requestor.error", //$NON-NLS-1$
+					Integer.toString(globalErrorCount),
+					new String(problem.getOriginatingFileName()))
+				: Main.bind(
+					"requestor.warning", //$NON-NLS-1$
+					Integer.toString(globalErrorCount),
+					new String(problem.getOriginatingFileName())));
+			try {
+				this.printlnErr(((DefaultProblem) problem).errorReportSource(unitSource));
+				this.printlnErr(problem.getMessage());
+			} catch (Exception e) {
+				this.printlnErr(Main.bind(
+					"requestor.notRetrieveErrorMessage", problem.toString())); //$NON-NLS-1$
+			}
+			this.printlnErr("----------"); //$NON-NLS-1$
+		}
+		
+		/**
+		 * @param globalProblemsCount
+		 * @param globalErrorsCount
+		 * @param globalWarningsCount
+		 */
+		public void logProblemsSummary(int globalProblemsCount,
+			int globalErrorsCount, int globalWarningsCount, int globalTasksCount) {
+			if (this.isXml) {
+				// generate xml
+				parameters.clear();
+				parameters.put(NUMBER_OF_PROBLEMS, new Integer(globalProblemsCount));
+				parameters.put(NUMBER_OF_ERRORS, new Integer(globalErrorsCount));
+				parameters.put(NUMBER_OF_WARNINGS, new Integer(globalWarningsCount));
+				parameters.put(NUMBER_OF_TASKS, new Integer(globalTasksCount));
+				this.printTag(PROBLEM_SUMMARY, parameters, true, true);
+			}
+			if (globalProblemsCount == 1) {
+				String message = null;
+				if (globalErrorsCount == 1) {
+					message = Main.bind("compile.oneError"); //$NON-NLS-1$
+				} else {
+					message = Main.bind("compile.oneWarning"); //$NON-NLS-1$
+				}
+				this.printErr(Main.bind("compile.oneProblem", message)); //$NON-NLS-1$
+			} else {
+				String errorMessage = null;
+				String warningMessage = null;
+				if (globalErrorsCount > 0) {
+					if (globalErrorsCount == 1) {
+						errorMessage = Main.bind("compile.oneError"); //$NON-NLS-1$
+					} else {
+						errorMessage = Main.bind("compile.severalErrors", String.valueOf(globalErrorsCount)); //$NON-NLS-1$
+					}
+				}
+				int warningsNumber = globalWarningsCount + globalTasksCount;
+				if (warningsNumber > 0) {
+					if (warningsNumber == 1) {
+						warningMessage = Main.bind("compile.oneWarning"); //$NON-NLS-1$
+					} else {
+						warningMessage = Main.bind("compile.severalWarnings", String.valueOf(warningsNumber)); //$NON-NLS-1$
+					}
+				}
+				if (errorMessage == null || warningMessage == null) {
+					if (errorMessage == null) {
+						this.printErr(Main.bind(
+							"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
+							String.valueOf(globalProblemsCount),
+							warningMessage));
+					} else {
+						this.printErr(Main.bind(
+							"compile.severalProblemsErrorsOrWarnings", //$NON-NLS-1$
+							String.valueOf(globalProblemsCount),
+							errorMessage));
+					}
+				} else {
+					this.printErr(Main.bind(
+						"compile.severalProblemsErrorsAndWarnings", //$NON-NLS-1$
+						new String[] {
+							String.valueOf(globalProblemsCount),
+							errorMessage,
+							warningMessage
+						}));
+				}
+			}
+		}
+
+		public int logProblems(IProblem[] problems, char[] unitSource, Main currentMain) {
+			final int count = problems.length;
+			int localErrorCount = 0;
+			if (count != 0) {
+				if (this.isXml) {
+					int errors = 0;
+					int warnings = 0;
+					int tasks = 0;
+					for (int i = 0; i < count; i++) {
+						IProblem problem = problems[i];
+						if (problem != null) {
+							currentMain.globalProblemsCount++;
+							this.logProblem(problem, localErrorCount, currentMain.globalProblemsCount, unitSource);
+							if (problem.isError()) {
+								errors++;
+								currentMain.globalErrorsCount++;
+								localErrorCount++;
+							} else if (problem.getID() == IProblem.Task) {
+								currentMain.globalTasksCount++;
+								tasks++;
+							} else {
+								currentMain.globalWarningsCount++;
+								warnings++;
+							}
+						}
+					}
+					if ((errors + warnings) != 0) {
+						this.startLoggingProblems(errors, warnings);
+						for (int i = 0; i < count; i++) {
+							IProblem problem = problems[i];
+							if (problem!= null) {
+								if (problem.getID() != IProblem.Task) {
+									this.logXmlProblem(problem, unitSource);
+								}
+							}
+						}
+						this.endLoggingProblems();
+					}
+					if (tasks != 0) {
+						this.startLoggingTasks(tasks);
+						for (int i = 0; i < count; i++) {
+							IProblem problem = problems[i];
+							if (problem!= null) {
+								if (problem.getID() == IProblem.Task) {
+									this.logXmlTask(problem, unitSource);
+								}
+							}
+						}
+						this.endLoggingTasks();
+					}
+				} else {
+					for (int i = 0; i < count; i++) {
+						if (problems[i] != null) {
+							currentMain.globalProblemsCount++;
+							this.logProblem(problems[i], localErrorCount, currentMain.globalProblemsCount, unitSource);
+							if (problems[i].isError()) {
+								currentMain.globalErrorsCount++;
+								localErrorCount++;
+							} else {
+								currentMain.globalWarningsCount++;
+							}
+						}
+					}
+				}
+			}
+			return localErrorCount;
+		}
+		
+		/**
+		 * 
+		 */
+		public void logProgress() {
+			this.printOut('.');
+		}
+
+		/**
+		 * @param i
+		 *            the current repetition number
+		 * @param repetitions
+		 *            the given number of repetitions
+		 */
+		public void logRepetition(int i, int repetitions) {
+			this.printlnOut(Main.bind("compile.repetition", //$NON-NLS-1$
+				String.valueOf(i + 1), String.valueOf(repetitions)));
+		}
+
+		public void printStats(Main main) {
+			final boolean isTimed = main.timing;
+			if (isXml) {
+				this.printTag(STATS, null, true, false);
+			}
+			if (isTimed) {
+				long time = System.currentTimeMillis() - main.startTime;
+				this.logTiming(time, main.lineCount);
+				if (main.times != null) {
+					main.times[main.timesCounter++] = time;
+				}
+			}
+			if (main.globalProblemsCount > 0) {
+				this.logProblemsSummary(main.globalProblemsCount, main.globalErrorsCount, main.globalWarningsCount, main.globalTasksCount);
+			}
+			if (main.exportedClassFilesCounter != 0
+					&& (main.showProgress || isTimed || main.verbose)) {
+				this.logNumberOfClassFilesGenerated(main.exportedClassFilesCounter);
+			}
+			if (isXml) {
+				this.endTag(STATS);
+			}
+		}
+		/**
+		 * @param time
+		 * @param lineCount
+		 */
+		public void logTiming(long time, long lineCount) {
+			if (isXml) {
+				this.parameters.clear();
+				this.parameters.put(VALUE, new Long(time));
+				this.printTag(TIME, this.parameters, true, true);
+				this.parameters.clear();
+				this.parameters.put(VALUE, new Long(lineCount));
+				this.printTag(NUMBER_OF_LINES, this.parameters, true, true);
+			}
+			if (lineCount != 0) {
+				this.printlnOut(Main.bind(
+					"compile.instantTime", //$NON-NLS-1$
+					new String[] {
+						String.valueOf(lineCount),
+						String.valueOf(time),
+						String.valueOf(((int) (lineCount * 10000.0 / time)) / 10.0) }));
+			} else {
+				this.printlnOut(Main.bind("compile.totalTime", String.valueOf(time))); //$NON-NLS-1$
+			}
+		}
+
+		/**
+		 * @param usage
+		 */
+		public void logUsage(String usage) {
+			this.printlnOut(usage); //$NON-NLS-1$//$NON-NLS-2$
+		}
+
+		/**
+		 * 
+		 */
+		public void logVersion() {
+			this.printlnOut(Main.bind("misc.version", //$NON-NLS-1$
+				new String[] {
+					Main.bind("compiler.name"), //$NON-NLS-1$
+					Main.bind("compiler.version"), //$NON-NLS-1$
+					Main.bind("compiler.copyright") //$NON-NLS-1$
+				}
+			)); //$NON-NLS-1$
+		}
+
+		/**
+		 * 
+		 */
+		public void logWrongJDK() {
+			if (isXml) {
+				parameters.clear();
+				parameters.put(MESSAGE, Main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$//$NON-NLS-2$
+				this.printTag(ERROR, parameters, true, true);				
+			}
+			this.printlnErr(Main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+		}
+
+		/**
+		 * @param problem
+		 *            the given problem to log
+		 * @param unitSource
+		 *            the given unit source
+		 */
+		private void logXmlProblem(IProblem problem, char[] unitSource) {
+			final int sourceStart = problem.getSourceStart();
+			final int sourceEnd = problem.getSourceEnd();
+			this.parameters.clear();
+			this.parameters.put(PROBLEM_ID, getFieldName(problem.getID()));
+			this.parameters.put(PROBLEM_SEVERITY, problem.isError() ? ERROR : WARNING);
+			this.parameters.put(PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+			this.parameters.put(PROBLEM_SOURCE_START, new Integer(sourceStart));
+			this.parameters.put(PROBLEM_SOURCE_END, new Integer(sourceEnd));
+			this.printTag(PROBLEM_TAG, parameters, true, false);
+			this.parameters.clear();
+			this.parameters.put(VALUE, problem.getMessage());
+			this.printTag(PROBLEM_MESSAGE, parameters, true, true);
+			this.parameters.clear();
+			extractContext(problem, unitSource);
+			this.printTag(SOURCE_CONTEXT, this.parameters, true, true);
+			String[] arguments = problem.getArguments();
+			final int length = arguments.length;
+			if (length != 0) {
+				this.printTag(PROBLEM_ARGUMENTS, null, true, false);
+				this.parameters.clear();
+				for (int i = 0; i < length; i++) {
+					this.parameters.put(PROBLEM_ARGUMENT_VALUE, arguments[i]);
+					this.printTag(PROBLEM_ARGUMENT, this.parameters, true, true);
+				}
+				this.endTag(PROBLEM_ARGUMENTS);
+			}
+			this.endTag(PROBLEM_TAG);
+		}
+		/**
+		 * @param problem
+		 *            the given problem to log
+		 * @param unitSource
+		 *            the given unit source
+		 */
+		private void logXmlTask(IProblem problem, char[] unitSource) {
+			this.parameters.clear();
+			this.parameters.put(PROBLEM_LINE, new Integer(problem.getSourceLineNumber()));
+			this.parameters.put(PROBLEM_SOURCE_START, new Integer(problem.getSourceStart()));
+			this.parameters.put(PROBLEM_SOURCE_END, new Integer(problem.getSourceEnd()));
+			this.printTag(TASK, this.parameters, true, false);
+			this.parameters.clear();
+			this.parameters.put(VALUE, problem.getMessage());
+			this.printTag(PROBLEM_MESSAGE, this.parameters, true, true);
+			this.parameters.clear();
+			extractContext(problem, unitSource);
+			this.printTag(SOURCE_CONTEXT, this.parameters, true, true);
+			this.endTag(TASK);
+		}
+		private void printErr(String s) {
 			this.err.print(s);
-			if (this.log != null) {
-				this.log.print(s);
+			if (!this.isXml) {
+				if (this.log != null) {
+					this.log.print(s);
+				}
 			}
 		}
-		
-		public void printlnErr(String s) {
+
+		private void printlnErr(String s) {
 			this.err.println(s);
-			if (this.log != null) {
-				this.log.println(s);
+			if (!this.isXml) {
+				if (this.log != null) {
+					this.log.println(s);
+				}
 			}
 		}
-		
-		public void printlnOut(String s) {
+
+		private void printlnOut(String s) {
 			this.out.println(s);
 		}
-		
-		public void printlnOut() {
+
+		/**
+		 * 
+		 */
+		public void printNewLine() {
 			this.out.println();
 		}
-		
-		public void printOut(char c) {
+
+		private void printOut(char c) {
 			this.out.print(c);
 		}
+		public void printTag(String name, HashMap params, boolean insertNewLine, boolean closeTag) {
+			for (int i= this.tab; i > 0; i--) this.log.print('\t');
+			StringBuffer buffer= new StringBuffer();
+			buffer.append("<"); //$NON-NLS-1$
+			buffer.append(name);
+			if (params != null) {
+				for (Enumeration enumeration = Collections.enumeration(params.keySet()); enumeration.hasMoreElements();) {
+					buffer.append(" "); //$NON-NLS-1$
+					String key= (String) enumeration.nextElement();
+					buffer.append(key);
+					buffer.append("=\""); //$NON-NLS-1$
+					buffer.append(getEscaped(String.valueOf(params.get(key))));
+					buffer.append("\""); //$NON-NLS-1$
+				}
+			}
+			if (closeTag) {
+				buffer.append("/>"); //$NON-NLS-1$
+			} else {
+				buffer.append(">"); //$NON-NLS-1$
+				this.tab++;
+			}
+			if (insertNewLine) {
+				this.log.println(String.valueOf(buffer));
+			} else {
+				this.log.print(String.valueOf(buffer));
+			}
+		}
+
+		public void setLog(String logFileName) throws InvalidInputException {
+			try {
+				this.log = new PrintWriter(new FileOutputStream(logFileName, false));
+				int index = logFileName.lastIndexOf('.');
+				if (index != 0) {
+					if (logFileName.substring(index).toLowerCase().equals(".xml")) { //$NON-NLS-1$
+						this.isXml = true;
+						this.log.println(XML_HEADER);
+						this.log.println(XML_DTD_DECLARATION);
+						this.tab = 0;
+						parameters.clear();
+						parameters.put(COMPILER_NAME, Main.bind("compiler.name")); //$NON-NLS-1$//$NON-NLS-2$
+						parameters.put(COMPILER_VERSION, Main.bind("compiler.version")); //$NON-NLS-1$//$NON-NLS-2$
+						parameters.put(COMPILER_COPYRIGHT, Main.bind("compiler.copyright")); //$NON-NLS-1$//$NON-NLS-2$
+						this.printTag(COMPILER, parameters, true, false);
+					}
+				}
+			} catch (FileNotFoundException e) {
+				throw new InvalidInputException(Main.bind("configure.cannotOpenLog")); //$NON-NLS-1$
+			}
+		}
+
+		/**
+		 * Used to start logging problems.
+		 * Only use in xml mode.
+		 */
+		private void startLoggingProblems(int errors, int warnings) {
+			parameters.clear();
+			parameters.put(NUMBER_OF_PROBLEMS, new Integer(errors + warnings));
+			parameters.put(NUMBER_OF_ERRORS, new Integer(errors));
+			parameters.put(NUMBER_OF_WARNINGS, new Integer(warnings));
+			this.printTag(PROBLEMS, this.parameters, true, false);
+		}
+		public void startLoggingSource(CompilationResult compilationResult) {
+			if (this.isXml) {
+				ICompilationUnit compilationUnit = compilationResult.compilationUnit;
+				char[] fileName = compilationUnit.getFileName();
+				File f = new File(new String(fileName));
+				if (fileName != null) {
+					this.parameters.clear();
+					if (compilationUnit != null) {
+						this.parameters.put(PATH, f.getAbsolutePath());
+					}
+				}
+				this.printTag(SOURCE, this.parameters, true, false);
+			}
+		}
+		public void startLoggingSources() {
+			if (this.isXml) {
+				this.printTag(SOURCES, null, true, false);
+			}
+		}
+		public void startLoggingTasks(int tasks) {
+			if (this.isXml) {
+				parameters.clear();
+				parameters.put(NUMBER_OF_TASKS, new Integer(tasks));
+				this.printTag(TASKS, this.parameters, true, false);
+			}
+		}
 	}
 	static {
 		relocalize();
@@ -114,16 +925,15 @@
 	public final static String bundleName =
 		"org.eclipse.jdt.internal.compiler.batch.messages"; 	//$NON-NLS-1$
 
-	public final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
-	public final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
 	public String[] classpaths;
 	public String destinationPath;
 	public String[] encodings;
-	public Logger logger;	
+	public Logger logger;
 	public int exportedClassFilesCounter;
 	public String[] filenames;
 	public boolean generatePackagesStructure;
 	public int globalErrorsCount;
+	public int globalTasksCount;
 	public int globalProblemsCount;
 	public int globalWarningsCount;
 	public long lineCount;
@@ -143,6 +953,8 @@
 	public boolean systemExitWhenFinished = true;
 	public long startTime;
 	public boolean timing = false;
+	public long[] times;
+	public int timesCounter;
 	public boolean verbose = false;
 
 	public Main(PrintWriter outWriter, PrintWriter errWriter, boolean systemExitWhenFinished) {
@@ -199,57 +1011,7 @@
 			// the id we were looking for.  In most cases this is semi-informative so is not too bad.
 			return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
 		}
-		// for compatibility with MessageFormat which eliminates double quotes in original message
-		char[] messageWithNoDoubleQuotes =
-			CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
-		
-		message = new String(messageWithNoDoubleQuotes);
-		int length = message.length();
-		int start = -1;
-		int end = length;
-		StringBuffer output = null;
-		while (true) {
-			if ((end = message.indexOf('{', start)) > -1) {
-				if (output == null) output = new StringBuffer(80);
-				output.append(message.substring(start + 1, end));
-				if ((start = message.indexOf('}', end)) > -1) {
-					int index = -1;
-					try {
-						String argId = message.substring(end + 1, start);
-						index = Integer.parseInt(argId);
-						if (arguments[index] == null) {
-							output.append('{').append(argId).append('}'); // leave parameter in since no better arg '{0}'
-						} else {
-							output.append(arguments[index]);
-						}						
-					} catch (NumberFormatException nfe) { // could be nested message ID {compiler.name}
-						String argId = message.substring(end + 1, start);
-						boolean done = false;
-						if (!id.equals(argId)) {
-							String argMessage = null;
-							try {
-								argMessage = bundle.getString(argId);
-								output.append(argMessage);
-								done = true;
-							} catch (MissingResourceException e) {
-								// missing the right resource
-							}
-						}
-						if (!done) output.append(message.substring(end + 1, start + 1));
-					} catch (ArrayIndexOutOfBoundsException e) {
-						output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
-					}
-				} else {
-					output.append(message.substring(end, length));
-					break;
-				}
-			} else {
-				if (output == null) return message;
-				output.append(message.substring(start + 1, length));
-				break;
-			}
-		}
-		return output.toString();
+		return MessageFormat.format(message, arguments);
 	}
 
 	/*
@@ -354,35 +1116,34 @@
 //				if (this.verbose) {
 //					System.out.println(new CompilerOptions(this.options));
 //				}
-				if (this.showProgress)
-					this.logger.printlnOut(Main.bind("progress.compiling")); //$NON-NLS-1$
+				if (this.showProgress) this.logger.compiling(); //$NON-NLS-1$
 				for (int i = 0; i < this.repetitions; i++) {
 					this.globalProblemsCount = 0;
 					this.globalErrorsCount = 0;
 					this.globalWarningsCount = 0;
+					this.globalTasksCount = 0;
 					this.lineCount = 0;
 					this.exportedClassFilesCounter = 0;
 
 					if (this.repetitions > 1) {
 						this.logger.flush();
-						this.logger.printlnOut(
-							Main.bind(
-								"compile.repetition", //$NON-NLS-1$
-								String.valueOf(i + 1),
-								String.valueOf(this.repetitions)));
+						this.logger.logRepetition(i, this.repetitions);
 					} 
 					// request compilation
 					performCompilation();
 				}
-				if (this.showProgress)
-					this.logger.printlnOut();
+				if (this.times != null) {
+					this.logger.logAverage(this.times, this.lineCount);
+				}
+				if (this.showProgress) this.logger.printNewLine();
 			}
 			if (this.systemExitWhenFinished) {
 				this.logger.flush();
+    			this.logger.close();
 				System.exit(this.globalErrorsCount > 0 ? -1 : 0);
 			}
 		} catch (InvalidInputException e) {
-			this.logger.printlnErr(e.getMessage());
+			this.logger.logException(e);
 			if (this.systemExitWhenFinished) {
     			this.logger.flush();
     			this.logger.close();
@@ -396,7 +1157,6 @@
 				System.exit(-1);
 			}
 			return false;
-			//e.printStackTrace();
 		} finally {
 			this.logger.flush();
 			this.logger.close();
@@ -596,7 +1356,7 @@
 				mode = Default;
 				continue;
 			}
-			if (currentArg.equals("-1.5")) { //$NON-NLS-1$
+			if (currentArg.equals("-1.5") || currentArg.equals("-5") || currentArg.equals("-5.0")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 				if (didSpecifyCompliance) {
 					throw new InvalidInputException(
 						Main.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
@@ -995,6 +1755,10 @@
 						this.options.put(
 							CompilerOptions.OPTION_ReportUnqualifiedFieldAccess,
 							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
+					} else if (token.equals("typeHiding")) { //$NON-NLS-1$
+						this.options.put(
+							CompilerOptions.OPTION_ReportTypeParameterHiding,
+							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
 					} else if (token.equals("varargsCast")) { //$NON-NLS-1$
 						this.options.put(
 							CompilerOptions.OPTION_ReportVarargsArgumentNeedCast,
@@ -1007,6 +1771,22 @@
 						this.options.put(
 							CompilerOptions.OPTION_ReportAutoboxing,
 							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);						
+					} else if (token.equals("Override")) { //$NON-NLS-1$
+						this.options.put(
+							CompilerOptions.OPTION_ReportMissingOverrideAnnotation,
+							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);						
+					} else if (token.equals("Deprecated")) { //$NON-NLS-1$
+						this.options.put(
+							CompilerOptions.OPTION_ReportMissingDeprecatedAnnotation,
+							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);						
+					} else if (token.equals("intfAnnotation")) { //$NON-NLS-1$
+						this.options.put(
+							CompilerOptions.OPTION_ReportAnnotationSuperInterface,
+							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);						
+					} else if (token.equals("enumSwitch")) { //$NON-NLS-1$
+						this.options.put(
+							CompilerOptions.OPTION_ReportIncompleteEnumSwitch,
+							isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);						
 					} else {
 						throw new InvalidInputException(Main.bind("configure.invalidWarning", token)); //$NON-NLS-1$
 					}
@@ -1052,7 +1832,7 @@
 						throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_4)); //$NON-NLS-1$
 					}
 					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
-				} else if (currentArg.equals("1.5") || currentArg.equals("5")) { //$NON-NLS-1$//$NON-NLS-2$
+				} else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
 					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
 					if (didSpecifyCompliance && CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) < ClassFileConstants.JDK1_5) {
 						throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), CompilerOptions.VERSION_1_5)); //$NON-NLS-1$
@@ -1104,7 +1884,7 @@
 					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
 				} else if (currentArg.equals("1.4")) { //$NON-NLS-1$
 					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
-				} else if (currentArg.equals("1.5") || currentArg.equals("5")) { //$NON-NLS-1$//$NON-NLS-2$
+				} else if (currentArg.equals("1.5") || currentArg.equals("5") || currentArg.equals("5.0")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
 					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
 				} else {
 					throw new InvalidInputException(Main.bind("configure.source", currentArg)); //$NON-NLS-1$
@@ -1236,7 +2016,7 @@
 			// no user classpath specified.
 			String classProp = System.getProperty("java.class.path"); //$NON-NLS-1$
 			if ((classProp == null) || (classProp.length() == 0)) {
-				this.logger.printlnErr(Main.bind("configure.noClasspath")); //$NON-NLS-1$
+				this.logger.logNoClasspath(); //$NON-NLS-1$
 				classProp = System.getProperty("user.dir"); //$NON-NLS-1$
 			}
 			StringTokenizer tokenizer = new StringTokenizer(classProp, File.pathSeparator);
@@ -1254,7 +2034,7 @@
 			 */
 			 String javaversion = System.getProperty("java.version");//$NON-NLS-1$
 			 if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$
-				this.logger.printlnErr(Main.bind("configure.requiresJDK1.2orAbove")); //$NON-NLS-1$
+				this.logger.logWrongJDK(); //$NON-NLS-1$
 				this.proceed = false;
 				return;
 			 }
@@ -1291,11 +2071,7 @@
 		}
 
 		if (this.log != null) {
-			try {
-				this.logger.setLog(new PrintWriter(new FileOutputStream(this.log, false)));
-			} catch (IOException e) {
-				throw new InvalidInputException(Main.bind("configure.cannotOpenLog")); //$NON-NLS-1$
-			}
+			this.logger.setLog(this.log);
 		} else {
 			this.showProgress = false;
 		}
@@ -1331,7 +2107,7 @@
 		for (int i = 0, max = this.classpaths.length; i < max; i++) {
 			File file = new File(this.classpaths[i]);
 			if (!file.exists()) { // signal missing classpath entry file
-				this.logger.printlnErr(Main.bind("configure.incorrectClasspath", this.classpaths[i])); //$NON-NLS-1$
+				this.logger.logIncorrectClasspath(this.classpaths[i]); //$NON-NLS-1$
 			}
 		}
 		if (this.destinationPath == null) {
@@ -1343,24 +2119,24 @@
 		if (didSpecifyCompliance) {
 			Object version = this.options.get(CompilerOptions.OPTION_Compliance);
 			if (CompilerOptions.VERSION_1_3.equals(version)) {
-					if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
-					if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
+				if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+				if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1);
 			} else if (CompilerOptions.VERSION_1_4.equals(version)) {
-					if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
-					if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
+				if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
+				if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
 			} else if (CompilerOptions.VERSION_1_5.equals(version)) {
-					if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
-					if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+				if (!didSpecifySource) this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+				if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
 			}
 		}
 		if (didSpecifySource) {
 			Object version = this.options.get(CompilerOptions.OPTION_Source);
 			 if (CompilerOptions.VERSION_1_4.equals(version)) {
-					if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
-					if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+				if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
+				if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
 			} else if (CompilerOptions.VERSION_1_5.equals(version)) {
-					if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
-					if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
+				if (!didSpecifyCompliance) this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+				if (!didSpecifyTarget) this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
 			}
 		}
 
@@ -1378,7 +2154,7 @@
 	   		}
 			// target cannot be greater than compliance level
 			if (CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_Compliance)) < CompilerOptions.versionToJdkLevel(this.options.get(CompilerOptions.OPTION_TargetPlatform))){ 
-					throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), (String)this.options.get(CompilerOptions.OPTION_TargetPlatform))); //$NON-NLS-1$
+				throw new InvalidInputException(Main.bind("configure.incompatibleComplianceForTarget", (String)this.options.get(CompilerOptions.OPTION_Compliance), (String)this.options.get(CompilerOptions.OPTION_TargetPlatform))); //$NON-NLS-1$
 			}
 		}
 
@@ -1412,10 +2188,16 @@
 				}
 			}
 		}
-
+		this.logger.logCommandLineArguments(newCommandLineArgs);
+		this.logger.logOptions(this.options);
+		this.logger.logClasspath(this.classpaths);
 		if (this.repetitions == 0) {
 			this.repetitions = 1;
 		}
+		if (this.repetitions >= 3 && this.timing) {
+			this.times = new long[this.repetitions];
+			this.timesCounter = 0;
+		}
 	}
 
 	private void disableWarnings() {
@@ -1441,7 +2223,7 @@
 			if (lastIndex == -1) {
 				return System.getProperty("user.dir"); //$NON-NLS-1$
 			}
-			return new String(CharOperation.subarray(fileName, 0, lastIndex));
+			return new String(fileName, 0, lastIndex);
 		}
 		return System.getProperty("user.dir"); //$NON-NLS-1$
 	}
@@ -1456,57 +2238,26 @@
 					int unitLineCount = compilationResult.lineSeparatorPositions.length;
 					Main.this.lineCount += unitLineCount;
 					this.lineDelta += unitLineCount;
-					if (Main.this.showProgress
-						&& this.lineDelta > 2000) { // in -log mode, dump a dot every 2000 lines compiled
-						Main.this.logger.printOut('.');
+					if (Main.this.showProgress && this.lineDelta > 2000) {
+						// in -log mode, dump a dot every 2000 lines compiled
+						Main.this.logger.logProgress();
 						this.lineDelta = 0;
 					}
 				}
+				Main.this.logger.startLoggingSource(compilationResult);
 				if (compilationResult.hasProblems() || compilationResult.hasTasks()) {
-					IProblem[] problems = compilationResult.getAllProblems();
-					int count = problems.length;
-					int localErrorCount = 0;
-					char[] unitSource = compilationResult.compilationUnit.getContents();
-					for (int i = 0; i < count; i++) {
-						if (problems[i] != null) {
-							Main.this.globalProblemsCount++;
-							if (localErrorCount == 0)
-								Main.this.logger.printlnErr("----------"); //$NON-NLS-1$
-							Main.this.logger.printErr(
-								Main.this.globalProblemsCount
-									+ ". "  //$NON-NLS-1$
-									+ (problems[i].isError()
-										? Main.bind("requestor.error")  //$NON-NLS-1$
-										: Main.bind("requestor.warning")));  //$NON-NLS-1$
-							if (problems[i].isError()) {
-								Main.this.globalErrorsCount++;
-							} else {
-								Main.this.globalWarningsCount++;
-							}
-							Main.this.logger.printErr(" "); //$NON-NLS-1$
-							Main.this.logger.printErr(
-								Main.bind("requestor.in", new String(problems[i].getOriginatingFileName()))); //$NON-NLS-1$
-							try {
-								Main.this.logger.printlnErr(
-									((DefaultProblem) problems[i]).errorReportSource(unitSource));
-								Main.this.logger.printlnErr(problems[i].getMessage());
-							} catch (Exception e) {
-								Main.this.logger.printlnErr(
-									Main.bind("requestor.notRetrieveErrorMessage", problems[i].toString())); //$NON-NLS-1$
-							}
-							Main.this.logger.printlnErr("----------"); //$NON-NLS-1$
-							if (problems[i].isError())
-								localErrorCount++;
-						}
-					}
+					int localErrorCount = Main.this.logger.logProblems(compilationResult.getAllProblems(), compilationResult.compilationUnit.getContents(), Main.this);
 					// exit?
 					if (Main.this.systemExitWhenFinished && !Main.this.proceedOnError && (localErrorCount > 0)) {
-						Main.this.printStats();
+						Main.this.logger.endLoggingSource();
+						Main.this.logger.printStats(Main.this);
 						Main.this.logger.flush();
+						Main.this.logger.close();
 						System.exit(-1);
 					}
 				}
 				outputClassFiles(compilationResult);
+				Main.this.logger.endLoggingSource();
 			}
 		};
 	}
@@ -1603,39 +2354,12 @@
 	// Dump classfiles onto disk for all compilation units that where successfull.
 
 	public void outputClassFiles(CompilationResult unitResult) {
-
 		if (!((unitResult == null) || (unitResult.hasErrors() && !this.proceedOnError))) {
 			Enumeration classFiles = unitResult.compiledTypes.elements();
 			if (!this.generatePackagesStructure) {
-				while (classFiles.hasMoreElements()) {
-					this.destinationPath = extractDestinationPathFromSourceFile(unitResult);
-					// retrieve the key and the corresponding classfile
-					ClassFile classFile = (ClassFile) classFiles.nextElement();
-					char[] filename = classFile.fileName();
-					int length = filename.length;
-					char[] relativeName = new char[length + 6];
-					System.arraycopy(filename, 0, relativeName, 0, length);
-					System.arraycopy(SUFFIX_class, 0, relativeName, length, 6);
-					CharOperation.replace(relativeName, '/', File.separatorChar);
-					try {
-						if (this.compilerOptions.verbose)
-							System.out.println(Util.bind("compilation.write", //$NON-NLS-1$
-								new String[] {
-									String.valueOf(this.exportedClassFilesCounter+1),
-									new String(relativeName) }));					    
-						ClassFile.writeToDisk(
-							this.generatePackagesStructure,
-							this.destinationPath,
-							new String(relativeName),
-							classFile.getBytes());
-					} catch (IOException e) {
-						String fileName = this.destinationPath + new String(relativeName);
-						e.printStackTrace();
-						this.logger.printlnErr(Main.bind("output.noClassFileCreated", fileName));  //$NON-NLS-1$
-					}
-					this.exportedClassFilesCounter++;
-				}
-			} else if (this.destinationPath != null) {
+				this.destinationPath = extractDestinationPathFromSourceFile(unitResult);
+			}
+			if (this.destinationPath != null) {
 				while (classFiles.hasMoreElements()) {
 					// retrieve the key and the corresponding classfile
 					ClassFile classFile = (ClassFile) classFiles.nextElement();
@@ -1645,21 +2369,29 @@
 					System.arraycopy(filename, 0, relativeName, 0, length);
 					System.arraycopy(SUFFIX_class, 0, relativeName, length, 6);
 					CharOperation.replace(relativeName, '/', File.separatorChar);
+					String relativeStringName = new String(relativeName);
 					try {
 						if (this.compilerOptions.verbose)
-							System.out.println(Util.bind("compilation.write", //$NON-NLS-1$
-								new String[] {
-									String.valueOf(this.exportedClassFilesCounter+1),
-									new String(relativeName) }));					    
+							System.out.println(
+								Messages.bind(
+									Messages.compilation_write,
+									new String[] {
+										String.valueOf(this.exportedClassFilesCounter+1),
+										relativeStringName
+									}));
 						ClassFile.writeToDisk(
 							this.generatePackagesStructure,
 							this.destinationPath,
-							new String(relativeName),
+							relativeStringName,
 							classFile.getBytes());
+						this.logger.logClassFile(
+							this.generatePackagesStructure,
+							this.destinationPath,
+							relativeStringName);
 					} catch (IOException e) {
-						String fileName = this.destinationPath + new String(relativeName);
+						String fileName = this.destinationPath + relativeStringName;
 						e.printStackTrace();
-						this.logger.printlnErr(Main.bind("output.noClassFileCreated", fileName)); //$NON-NLS-1$
+						this.logger.logNoClassFileCreated(fileName); //$NON-NLS-1$
 					}
 					this.exportedClassFilesCounter++;
 				}
@@ -1686,77 +2418,32 @@
 		// set the non-externally configurable options.
 		this.compilerOptions.verbose = this.verbose;
 		this.compilerOptions.produceReferenceInfo = this.produceRefInfo;
-		batchCompiler.compile(getCompilationUnits());
+		try {
+			this.logger.startLoggingSources();
+			batchCompiler.compile(getCompilationUnits());
+		} finally {
+			this.logger.endLoggingSources();
+		}
 
-		printStats();
+		this.logger.printStats(this);
 		
 		// cleanup
 		environment.cleanup();
 	}
 	
-	public void printStats() {
-		if (this.timing) {
-
-			long time = System.currentTimeMillis() - this.startTime;
-			if (this.lineCount != 0) {
-				this.logger.printlnOut(
-					Main.bind(
-						"compile.instantTime", 	//$NON-NLS-1$
-						new String[] {
-							String.valueOf(this.lineCount),
-							String.valueOf(time),
-							String.valueOf(((int)(this.lineCount * 10000.0 / time)) / 10.0)}));
-			} else {
-				this.logger.printlnOut(Main.bind("compile.totalTime", String.valueOf(time))); //$NON-NLS-1$
-			}
-		}
-		if (this.globalProblemsCount > 0) {
-			if (this.globalProblemsCount == 1) {
-				this.logger.printErr(Main.bind("compile.oneProblem")); //$NON-NLS-1$
-			} else {
-				this.logger.printErr(
-					Main.bind("compile.severalProblems", String.valueOf(this.globalProblemsCount))); 	//$NON-NLS-1$
-			}
-			this.logger.printErr(" ("); //$NON-NLS-1$
-			if (this.globalErrorsCount > 0) {
-				if (this.globalErrorsCount == 1) {
-					this.logger.printErr(Main.bind("compile.oneError")); //$NON-NLS-1$
-				} else {
-					this.logger.printErr(
-						Main.bind("compile.severalErrors", String.valueOf(this.globalErrorsCount))); 	//$NON-NLS-1$
-				}
-			}
-			if (this.globalWarningsCount > 0) {
-				if (this.globalErrorsCount > 0) {
-					this.logger.printErr(", "); //$NON-NLS-1$
-				}
-				if (this.globalWarningsCount == 1) {
-					this.logger.printErr(Main.bind("compile.oneWarning")); //$NON-NLS-1$
-				} else {
-					this.logger.printErr(
-						Main.bind("compile.severalWarnings", String.valueOf(this.globalWarningsCount))); 	//$NON-NLS-1$
-				}
-			}
-			this.logger.printlnErr(")"); //$NON-NLS-1$
-		}
-		if (this.exportedClassFilesCounter != 0
-			&& (this.showProgress || this.timing || this.verbose)) {
-			if (this.exportedClassFilesCounter == 1) {
-				this.logger.printlnOut(Main.bind("compile.oneClassFileGenerated")); //$NON-NLS-1$
-			} else {
-				this.logger.printlnOut(
-					Main.bind(
-						"compile.severalClassFilesGenerated", //$NON-NLS-1$
-						String.valueOf(this.exportedClassFilesCounter)));
-			}
-		}
-	}
 	public void printUsage() {
-		this.logger.printlnOut(Main.bind("misc.usage", System.getProperty("path.separator"))); //$NON-NLS-1$//$NON-NLS-2$
+		this.logger.logUsage(Main.bind("misc.usage", //$NON-NLS-1$
+			new String[] {
+				System.getProperty("path.separator"), //$NON-NLS-1$
+				Main.bind("compiler.name"), //$NON-NLS-1$
+				Main.bind("compiler.version"), //$NON-NLS-1$
+				Main.bind("compiler.copyright") //$NON-NLS-1$
+			}
+		));
 		this.logger.flush();
 	}
 	public void printVersion() {
-		this.logger.printlnOut(Main.bind("misc.version"));  //$NON-NLS-1$
+		this.logger.logVersion();  //$NON-NLS-1$
 		this.logger.flush();
 	}
 }
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 5fc0791..22b7234 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -1,10 +1,10 @@
 ###############################################################################
-# Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
@@ -14,7 +14,7 @@
 #Format: compiler.name = word1 word2 word3
 compiler.name = Eclipse Java Compiler
 #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.531, pre-3.1.0 milestone-5
+compiler.version = 0.553, pre-3.1.0 milestone-7
 compiler.copyright = Copyright IBM Corp 2000, 2005. All rights reserved.
 
 ### scanning
@@ -26,9 +26,11 @@
 ### compile
 compile.repetition = [repetition {0}/{1}]
 compile.instantTime = [compiled {0} lines in {1} ms: {2} lines/s]
+compile.averageTime = [average, excluding min-max {0} lines in {1} ms: {2} lines/s]
 compile.totalTime = [total compilation time: {0}]
-compile.oneProblem = 1 problem
-compile.severalProblems = {0} problems
+compile.oneProblem = 1 problem ({0})
+compile.severalProblemsErrorsOrWarnings = {0} problems ({1})
+compile.severalProblemsErrorsAndWarnings = {0} problems ({1}, {2})
 compile.oneError = 1 error
 compile.severalErrors = {0} errors
 compile.oneWarning = 1 warning
@@ -44,14 +46,14 @@
 configure.duplicateCompliance = duplicate compliance setting specification: {0}
 configure.duplicateSource = duplicate source compliance setting specification: {0}
 configure.duplicateTarget = duplicate target compliance setting specification: {0}
-configure.source = source level should be comprised in between ''1.3'' and ''1.5'' or ''5'': {0}
+configure.source = source level should be comprised in between ''1.3'' and ''1.5'' (or ''5'' or ''5.0''): {0}
 configure.duplicateOutputPath = duplicate output path specification: {0}
 configure.duplicateBootClasspath = duplicate bootclasspath specification: {0}
 configure.invalidDebugOption = invalid debug option: {0}
 configure.invalidWarningConfiguration = invalid warning configuration: {0}
 configure.invalidWarning = invalid warning: {0}
 configure.invalidWarningOption = invalid warning option: {0}
-configure.targetJDK = target level should be comprised in between ''1.1'' and ''1.5'' or ''5'': {0}
+configure.targetJDK = target level should be comprised in between ''1.1'' and ''1.5'' (or ''5'' or ''5.0''): {0}
 configure.incompatibleTargetForSource = Target level ''{0}'' is incompatible with source level ''{1}''. A target level ''{1}'' or better is required
 configure.incompatibleComplianceForSource = Compliance level ''{0}'' is incompatible with source level ''{1}''. A compliance level ''{1}'' or better is required
 configure.incompatibleComplianceForTarget = Compliance level ''{0}'' is incompatible with target level ''{1}''. A compliance level ''{1}'' or better is required
@@ -61,7 +63,7 @@
 configure.IOError = i/o error : unable to retrieve .JAVA files in directory: {0}
 configure.noClasspath = no classpath defined, using default directory instead
 configure.incorrectClasspath = incorrect classpath: {0}
-configure.invalidexpansionargumentname = expansion argument file {0} doesn't exist or cannot be read
+configure.invalidexpansionargumentname = expansion argument file {0} doesn''t exist or cannot be read
 configure.cannotOpenLog = cannot open .log file
 configure.unexpectedCustomEncoding = unexpected custom encoding specification: {0}[{1}]
 configure.unsupportedEncoding = unsupported encoding format: {0}
@@ -69,9 +71,8 @@
 configure.invalidTaskTag ={0} is an invalid task tag
 
 ### requestor
-requestor.error = ERROR
-requestor.warning = WARNING
-requestor.in = in {0}
+requestor.error = {0}. ERROR in {1}
+requestor.warning = {0}. WARNING in {1}
 requestor.notRetrieveErrorMessage = Cannot retrieve the error message for {0}
 
 ### unit
@@ -82,8 +83,8 @@
 output.noClassFileCreated = No .class file created for file named {0} because of an IOException.
 
 ### miscellaneous
-misc.version = {compiler.name} {compiler.version}, {compiler.copyright}
-misc.usage = {compiler.name} {compiler.version}, {compiler.copyright}\n\
+misc.version = {0} {1}, {2}
+misc.usage = {1} {2}, {3}\n\
 \ \n\
 \ Usage: <options> <source files | directories>\n\
 \ If directories are specified, then their source contents are compiled.\n\
@@ -103,8 +104,8 @@
 \    -1.3               use 1.3 compliance level (implicit -source 1.3 -target 1.1)\n\
 \    -1.4             + use 1.4 compliance level (implicit -source 1.3 -target 1.2)\n\
 \    -1.5               use 1.5 compliance level (implicit -source 1.5 -target 1.5)\n\
-\    -source <version>  set source level (1.3 to 1.5 or 5)\n\
-\    -target <version>  set classfile target level (1.1 to 1.5 or 5)\n\
+\    -source <version>  set source level: 1.3 to 1.5 (or 5 or 5.0)\n\
+\    -target <version>  set classfile target level: 1.1 to 1.5 (or 5 or 5.0)\n\
 \ \n\
 \ Warning options:\n\
 \    -deprecation     + deprecation outside deprecated code\n\
@@ -121,11 +122,14 @@
 \      conditionAssign      possible accidental boolean assignment\n\
 \      constructorName    + method with constructor name\n\
 \      deprecation        + deprecation outside deprecated code\n\
+\      Deprecated           missing @Deprecated annotation\n\
 \      emptyBlock           undocumented empty block\n\
+\      enumSwitch           incomplete enum switch\n\
 \      fieldHiding          field hiding another variable\n\
 \      finalBound           type parameter with final bound\n\
 \      finally            + finally block not completing normally\n\
 \      indirectStatic       indirect reference to static member\n\
+\      intfAnnotation     + annotation type used as super interface\n\
 \      intfNonInherited   + interface non-inherited method compatibility\n\
 \      javadoc              invalid javadoc\n\
 \      localHiding          local variable hiding another variable\n\
@@ -133,6 +137,7 @@
 \      nls                  string literal lacking non-nls tag //$NON-NLS-<n>$\n\
 \      noEffectAssign     + assignment without effect\n\
 \      nullCheck          + missing or redundant null check\n\
+\      Override             missing @Override annotation\n\
 \      pkgDefaultMethod   + attempt to override package-default method\n\
 \      semicolon            unnecessary semicolon, empty statement\n\
 \      serial             + missing serialVersionUID\n\
@@ -149,6 +154,7 @@
 \      staticReceiver     + non-static reference to static member\n\
 \      syntheticAccess      synthetic access for innerclass\n\
 \      tasks(<tags separated by |>) tasks identified by tags inside comments\n\
+\      typeHiding         + type parameter hiding another type\n\
 \      varargsCast        + varargs argument need explicit cast\n\
 \
 \ \n\
diff --git a/org.eclipse.jdt.core/build.properties b/org.eclipse.jdt.core/build.properties
index 35243e8..ba3b548 100644
--- a/org.eclipse.jdt.core/build.properties
+++ b/org.eclipse.jdt.core/build.properties
@@ -1,18 +1,20 @@
 ###############################################################################
-# Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
 bin.includes = plugin.xml,\
                plugin.properties,\
                about.html,\
-               *.jar,\
-               .options
+               .,\
+               jdtCompilerAdapter.jar,\
+               .options,\
+               META-INF/
 javadoc.packages = org.eclipse.jdt.core.*,\
                    org.eclipse.jdt.core.formatter.*,\
                    org.eclipse.jdt.core.compiler.*,\
@@ -21,15 +23,17 @@
                    org.eclipse.jdt.core.dom.*,\
                    org.eclipse.jdt.core.dom.rewrite.*,\
                    org.eclipse.jdt.core.search.*
-source.jdtcore.jar = batch/,\
-                     codeassist/,\
-                     compiler/,\
-                     eval/,\
-                     formatter/,\
-                     dom/,\
-                     model/,\
-                     search/
+source.. = 	 batch/,\
+	         codeassist/,\
+	         compiler/,\
+	         eval/,\
+	         formatter/,\
+	         dom/,\
+	         model/,\
+	         search/
 source.jdtCompilerAdapter.jar = antadapter/
-jars.compile.order=jdtcore.jar,jdtCompilerAdapter.jar
+jars.compile.order=.,jdtCompilerAdapter.jar
 jars.extra.classpath=platform:/plugin/org.apache.ant/lib/ant.jar
-src.includes=about.html,schema/
\ No newline at end of file
+src.includes = about.html,\
+               schema/,\
+               component.xml
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index d34328c..97faf17 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -3,25 +3,21 @@
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="Author" content="IBM">
-   <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
    <title>JDT/Core Release Notes</title>
-
+   <link rel="stylesheet" href="jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
-<body>
-
 <body text="#000000" bgcolor="#FFFFFF">
-&nbsp;
-
 <table border=0 cellspacing=5 cellpadding=2 width="100%" >
   <tr> 
-    <td align=left width="72%">
-      <font face="Verdana, Arial, Helvetica" size="+3"><b>jdt core - build notes 3.1 stream</b></font>
-      <br><font face="Arial, Helvetica, sans-serif" size="-2" color="#8080ff">java development tooling core</font></td>
+    <td align="left" width="72%" class="title1">
+      <font size="+3"><b>jdt core - build notes 3.1 stream</b></font>
+    </td>
   </tr>
-	<tr><td>&nbsp;</td></tr>
+  <tr><td td align="left" width="72%" class="title2"><font size="-2">java development tooling core</font></td></tr>
+  <tr><td>&nbsp;</td></tr>
   <tr>
-  	<td>
-	  <font face="Arial, Helvetica, sans-serif" size="-1">
+  	<td class="title3">
+	  <font size="-1">
 	  Here are the build notes for the Eclipse JDT/Core plug-in project 
 	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
 	  describing <a href="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
@@ -41,23 +37,1498 @@
   </tr>
 </table>
 
-<a name="v_531"></a>
+<a name="v_553"></a>
 <p><hr><h1>
 Eclipse Platform Build Notes&nbsp;<br>
 Java Development Tooling Core</h1>
-Eclipse SDK 3.1M5 - ?th January 2005
-<br>Project org.eclipse.jdt.core v_531
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_531">cvs</a>).
+Eclipse SDK 3.1M7 - 2?th April 2005
+<br>Project org.eclipse.jdt.core v_553
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_553">cvs</a>).
 <h2>
 What's new in this drop</h2>
 <ul>
-<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82004">bug 82004</a> required the index version to be incremented. 
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92059">92059</a>
+IVariableBinding#getJavaElement() thows NPE for array's 'length' field
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84551">84551</a>
+[1.5][compiler] compiler must not allow implicit static reference to outer type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89440">89440</a>
+[1.5][problems] Reference to member of parameterized type incorrectly marked as error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84973">84973</a>
+[1.5] parameterized inner type is illegal without parameterized  outer type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90484">90484</a>
+[1.5][compiler] Missing override annotation conflicts with Javac error checking
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81831">81831</a>
+[1.5][compiler] JDT compiler tries to infer the wildcard type "too early" in case of recursive generic type-bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89274">89274</a>
+[1.5][compiler] Enums in hierarchies with generics produces unnecessary warnings and errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90137">90137</a>
+[1.5][compiler] Collections.sort (List<Comparable>) compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90879">90879</a>
+[1.5][compiler] Cannot sort a raw Comparable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85281">85281</a>
+[1.5][compiler]  A<++Element> should not be assignable a  A<+Element>
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91091">91091</a>
+[quick assist] Cannot rename type name in file
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90881">90881</a>
+[1.5][compiler] NPE in builder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84496">84496</a>
+[1.5][compiler] Capture Conversion not correctly implemented
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=92086">92086</a>
+[index] ClassCastException in DiskIndex.mergeCategory()
+
+<a name="v_552"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 20th April 2005
+<br>Project org.eclipse.jdt.core v_552
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_552">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=91772">91772</a>
+Exported plugin dependencies are missing from the classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88769">88769</a>
+IMethodBinding#getJavaElement() drops extra array dimensions and varargs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88892">88892</a>
+[1.5] IMethodBinding#getJavaElement() returns nonexistent IMethods (wrong parameter types)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91445">91445</a>
+IMethodBinding.getJavaElement() returns an "unopen" IMethod
+	  	
+<a name="v_551"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 19th April 2005
+<br>Project org.eclipse.jdt.core v_551
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_551">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added performance instrumentation to track performance problem (use PerformanceStats from Core).<br>
+To enabled this Jdtcore instrumentation, you must add some new entries inside .options.
+<ul>
+<li><code>org.eclipse.jdt.core/perf/completion=300</code>: add an entry to performance.log if CompletionEngine.complete() take more than 300ms</li>
+<li><code>org.eclipse.jdt.core/perf/selection=300</code> add an entry to performance.log if SelectionEngine.select() take more than 300ms</li>
+<li><code>org.eclipse.jdt.core/perf/javadeltalistener=500</code> add an entry to performance.log if the call to the listener take more than 500ms</li>
+<li><code>org.eclipse.jdt.core/perf/variableinitializer=5000</code> add an entry to performance.log if the initialization take more than 5000ms</li>
+<li><code>org.eclipse.jdt.core/perf/containerinitializer=5000</code> add an entry to performance.log if the initialization take more than 5000ms</li>
+<li><code>org.eclipse.jdt.core/perf/reconcile=1000</code> add an entry to performance.log if ComplationUnit.reconcile() take more than 1000ms</li>
+</ul>
+Current default thresholds are not accurate and must be adjusted.
+</li>
+<li>Added support for completion inside single member annotation and annotation attribute value.
+<pre>
+@MyAnnotation(&lt;complete here&gt;
+@MyAnnotation(foo=&lt;complete here&gt;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91861">91861</a>
+Deadlock on startup while computing namelookup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89411">89411</a>
+ICompilationUnit#becomeWorkingCopy takes 18% of startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91716">91716</a>
+[prefs] Too many calls to EclipsePreference#get while scanning full workspace units
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90615">90615</a>
+Proposal for boolean
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84877">84877</a>
+Performance on startup
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91497">91497</a>
+[prefs] JavaCore should not give access to default preferences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90414">90414</a>
+[content assist] Content Assist fails when escape sequence present
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91438">91438</a>
+Need definitive set of jdt-core tests checked into cvs
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91498">91498</a>
+Reconcile still sees old access rules
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91221">91221</a>
+Code assist stopped working
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91371">91371</a>
+[assist] Stack Overflow - Field completion
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91098">91098</a>
+The Mark Occurrences feature does not mark all occurrences
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79288">79288</a>
+Code assist offers types which are out of scope ==> compile errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88298">88298</a>
+[1.5][assist] no completion inside SingleMemberAnnotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91238">91238</a>
+Malfunction of Format function
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=91160">91160</a>
+SourceField.getConstant() incorrect for char constants
+
+<a name="v_550"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 12th April 2005
+<br>Project org.eclipse.jdt.core v_550
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_550">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90431">bug 90431</a> required the index version to be incremented. 
      Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
 </li>
 </ul>
 
 <h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78698">78698</a>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89096">89096</a>
+Convert to new platform NLS support
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90302">90302</a>
+[javadoc] {@inheritedDoc} should be inactive for non-overridden method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90779">90779</a>
+[search] Constructor Declaration search with ignoring declaring and return type also ignores type name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90915">90915</a>
+[1.5][search] NPE in PatternLocator
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90266">90266</a>
+[select] Code select returns null when there's a string including a slash on same line
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90605">90605</a>
+Severity is not severe enough
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89470">89470</a>
+Generic Method override compatibility
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90446">90446</a>
+Update CreateTypeMemberOperation for changes in Indents 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90431">90431</a>
+Improve path lookup in scopes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90423">90423</a>
+[1.5][compiler] Generic method overloading. Javac allows but eclipse doesn't
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90213">90213</a>
+[Formatter] Redundant space in multidimensional array literals
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88263">88263</a>
+[1.5][compiler] Autobox and extends
+
+
+<a name="v_549"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M7 - 5th April 2005
+<br>Project org.eclipse.jdt.core v_549
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_549">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=89815">89815</a>
+Types not found using Open Type and search for declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77809">77809</a>
+[format] Line wrapping for enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=49896">49896</a>
+Formatters should have option to use tabs only for leading indents.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89777">89777</a>
+Improve doc formatting for IMethodBinding.getMethodDeclaration()
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=90111">90111</a>
+[1.5][compiler] Compiler warning "tagged with @Override" not correct with static methods
+
+<a name="v_548"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 1st April 2005
+<br>Project org.eclipse.jdt.core v_548 - 3.1 MILESTONE 6
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_548">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>
+New Code Formatter built-in profile has been added: "Eclipse [built-in]".<br>
+This new profile is based on "Java Conventions" but uses tab character (instead of space) and set tab size to 4 (instead of 8).<br>
+JavaCore was using these values by default but they were wrongly showed as "Java Conventions" in Code Formatter
+preference page. This problem is now fixed (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89739">89739</a>).<br>
+Code formatter behavior is still fully compatible with previous milestones for users who have not modified Code Formatter
+options in their workspace. However, users who have explicitely modified them and have troubles with use of tab character,
+should open Code Formatter preference page and either select this new "Eclipse" profile or verify state of "Use of tab character"
+check-box.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89982">89982</a>
+[1.5][compiler] Internal failure during missing enum  case diagnosis
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89848">89848</a>
+[search] does not find method references in anonymous class of imported jarred plugin
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89778">89778</a>
+NPE in bindThrownExceptions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89710">89710</a>
+[compiler] local variable range is wrong.
+
+
+<a name="v_547"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 31st March 2005
+<br>Project org.eclipse.jdt.core v_547
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_547">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=89739">89739</a>
+[prefs] Default for formatter should be Tab characters, not spaces
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89448">89448</a>
+Java Generics code throws a java.lang.NoClassDefFoundError
+
+
+<a name="v_546"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 31st March 2005
+<br>Project org.eclipse.jdt.core v_546
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_546">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In order to fix bugs <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=49896">49896</a> and <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=77809">77809</a>, we added the following
+two APIs:
+<ul>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS</code></li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89477">89477</a>
+[1.5][select] ArrayStoreException in SelectionEngine
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73658">73658</a>
+[1.5] Not all new 1.5 formatter options seem to work
+
+<a name="v_545"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 29th March 2005
+<br>Project org.eclipse.jdt.core v_545
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_545">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=81497">81497</a>
+[format] Wrong feeding after array-initialization
+
+<a name="v_544"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 29th March 2005
+<br>Project org.eclipse.jdt.core v_544
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_544">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>In order to fix <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73104">73104</a>, we have added the following new API:
+<ul><li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INDENTATION_SIZE</code></li>
+<li>Added new API <code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#MIXED</code>. This new constant is used for the option:
+<code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_CHAR</code>.</li>
+</ul>
+</li>
+<li>Added new API on <code>org.eclipse.jdt.core.dom.ITypeBinding#getDeclaringMethod()</code>. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86580">86580</a> for details.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89312">89312</a>
+API: BindingKey should probably be final
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89318">89318</a>
+[formatter] Option FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENTS has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89302">89302</a>
+[formatter] Insert space after comma in enum constants has no effect
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73104">73104</a>
+[format] indentation amount tied to tab size
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84872">84872</a>
+Improve string sharing in JavaModelCache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68148">68148</a>
+[model] Leaking persisted containers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89110">89110</a>
+Redundant information in SourceTypeElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89092">89092</a>
+Redundant information in ImportDeclarationElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89090">89090</a>
+Redundant information in SourceFieldElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89014">89014</a>
+IMethodBinding#isEqualTo(..) returns true for methods in different anonymous classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86580">86580</a>
+API on ITypeBinding for asking about the declaring node of type variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88575">88575</a>
+[1.5] treatment of Object.getClass() not API compliant
+
+<a name="v_543"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 24th March 2005
+<br>Project org.eclipse.jdt.core v_543
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_543">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added new kinds for the code formatter:
+<ul>
+<li><code>org.eclipse.jdt.core.formatter.CodeFormatter#K_SINGLE_LINE_COMMENT</code></li>
+<li><code>org.eclipse.jdt.core.formatter.CodeFormatter#K_MULTI_LINE_COMMENT</code></li>
+<li><code>org.eclipse.jdt.core.formatter.CodeFormatter#K_JAVA_DOC</code></li>
+</ul>
+</li>
+<li>Added new options to format comments:
+<ul>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_CLEAR_BLANK_LINES</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_HEADER</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_HTML</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT_SOURCE</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_FORMAT</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INDENT_ROOT_TAGS</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER</code></li>
+<li><code>org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMMENT_LINE_LENGTH</code></li>
+</ul>
+</li>
+<li>Added constant for the javadoc location attribute name: <code>IClasspathAttribute#JAVADOC_LOCATION_ATTRIBUTE_NAME</code>.</li>
+<li>Added API to create an array type binding key from a type key and array dimension: <code>BindingKey#createArrayTypeBindingKey(String typeKey, int arrayDimension)</code></li>
+<li>Added API to create a binding key from a type name: <code>BindingKey#createTypeBindingKey(String typeName)</code>.</li>
+<li>Added API to create a parameterized or raw type binding key from a generic type binding key and argument type binding keys:
+    <code>BindingKey#createParameterizedTypeBindingKey(String genericTypeKey, String[] argumentTypeKeys)</code>.</li>
+<li>Added API to create a type variable binding key from a type variable name and a declaring key: <code>createTypeVariableBindingKey(String typeVariableName, String declaringKey)</code></li>
+<li>Added API to create a wildcard binding key from a type key and wildcard kind: <code>BindingKey#createWildcardTypeBindingKey(String typeKey, char kind)</code></li>
+<li>Added API to query whether a field is an enum constant: <code>IField#isEnumConstant()</code></li>
+<li>Added API to code assist for access rule management.
+<ul>
+<li>Added JavaCore#CODEASSIST_FORBIDDEN_REFERENCE_CHECK and JavaCore#CODEASSIST_DISCOURAGED_REFERENCE_CHECK options</li>
+<li>Removed JavaCore#CODEASSIST_RESTRICTIONS_CHECK (Replaced by CODEASSIST_FORBIDDEN_REFERENCE)</li>
+<li>Added CompletionProposal#getAccessibility()</li>
+</ul>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=89088">89088</a>
+[performance] Scanner is sending 2 messages per identifier character
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83502">83502</a>
+Need API to create binding keys.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88845">88845</a>
+NPE in codeComplete for supertype that extends invisible type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70827">70827</a>
+[Search] wrong reference match to private method of supertype
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88300">88300</a>
+[search] Reference search result is changed by placement of private method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87173">87173</a>
+Surface compiler information about boxing/unboxing in the DOM AST (implicit conversion)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88841">88841</a>
+IAE while opening ASTView
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88548">88548</a>
+Need to get constant value on expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88921">88921</a>
+[Formatter] Adopt comment formatter from JDT/UI inside JDT/Core API
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88849">88849</a>
+Infinite loop in scanner when using eof=Integer.MAX_VALUE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88859">88859</a>
+Constant for the name of the Javadoc attribute
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=71460">71460</a>
+[model] Non *.java file association with Java contents.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88756">88756</a>
+[codeassist] Code assist propose anonymous enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76863">76863</a>
+[1.5][model] IField should offer a method isEnumConstant
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88757">88757</a>
+[API] SwitchStatement.statements() returns list of SwitchGroups
+
+<a name="v_542"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 22nd March 2005
+<br>Project org.eclipse.jdt.core v_542
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_542">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>The internal build state format has changed and a full build is expected when restarting an existing workspace with this version of JDT Core.</li>
+<li>Added the following APIs to control access rules severity:
+     <ul>
+     <li><code>org.eclipse.jdt.core.IAccessRule</code>
+           <ul>
+           <li><code>int K_ACCESSIBLE;</code></li>
+           <li><code>int K_NON_ACCESSIBLE;</code></li>
+           <li><code>int K_DISCOURAGED;</code></li>
+           <li><code>IPath getPattern();</code></li>
+           <li><code>int getKind();</code></li>
+           </ul>
+      </li>
+      <li><code>org.eclipse.jdt.core.JavaCore</code>
+           <ul>
+           <li><code>String COMPILER_PB_DISCOURAGED_REFERENCE;</code></li>
+           <li><code>IAccessRule newAccessRule(IPath pattern, int kind);</code></li>
+           <li><code>IClasspathEntry newContainerEntry(
+							IPath containerPath, 
+							IAccessRule[] accessRules, 
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           <li><code>IClasspathEntry newLibraryEntry(
+							IPath path,
+							IPath sourceAttachmentPath,
+							IPath sourceAttachmentRootPath,
+							IAccessRule[] accessRules, 
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           <li><code>IClasspathEntry newProjectEntry(
+							IPath path, 
+							IAccessRule[] accessRules, 
+							boolean combineAccessRules,
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           <li><code>IClasspathEntry newVariableEntry(
+							IPath variablePath,
+							IPath variableSourceAttachmentPath,
+							IPath variableSourceAttachmentRootPath,
+							IAccessRule[] accessRules, 
+							IClasspathAttribute[] extraAttributes,
+							boolean isExported);</code></li>
+           </ul>
+      </li>
+      <li><code>org.eclipse.jdt.core.IClasspathEntry</code>
+            <ul>
+           <li><code>boolean combineAccessRules();</code>
+           <li><code>IAccessRule[] getAccessRules();</code>
+           </ul>
+      </li>
+      </ul>
+</li>
+<li>Code select now works into Javadoc comment wherever a reference can be specified
+(ie. @see, @link, @linkplain, @throws, @exception, @param or @value tags)<br>
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54968">54968</a>).<br>
+For example, hit F3 with cursor located in <code>MyClass</code>, in following Javadoc comment:
+<pre>
+/**
+ * @see MyClass This is my class
+ */
+</pre>
+will open editor on MyClass.java file.
+</li>
+<li>New CodeSelect feature: Code select return an element if the selection is an enum constant inside a switch label.
+<pre>
+Colors c;
+swith(c) {
+  case BLUE:
+  case RED; // select RED
+}
+</pre>
+</li>
+<li>Added new kind of type signature: <code>Signature#WILDCARD_TYPE_SIGNATURE</code>.<br>
+<code>Signature#getTypeSignatureKind(char[])</code> and <code>Signature#getTypeSignatureKind(String)</code>
+now return <code>Signature#WILDCARD_TYPE_SIGNATURE</code> if the signature is a wildcard : * or +Ljava.lang.Object; or -Ljava.lang.Object;
+</li>
+<li>Added new completion API to describe context in which the completion occurs.<br>
+Currently only the expected types of the potential completion proposals are proposed.
+<pre>
+ X x = zzz&lt;complete here&gt;
+</pre>
+In this example the expected type is <code>X</code>. It is not mandatory to a proposal
+to respect this expectation and it is possible that there is no completion proposal.
+<pre>
+public class CompletionContext  {
+  public char[][] getExpectedTypesSignatures() {...}
+  public char[][] getExpectedTypesKeys() {...}
+}
+</pre>
+Client must override <code>CompletionRequestor#acceptContext(..)</code> to know the context.
+This method call ocurs after the call to <code>beginReporting()</code> and before the call to any
+<code>accept(CompletionProposal)</code> method.
+<pre>
+public class CompletionRequestor {
+  ...
+  public void acceptContext(CompletionContext context) {..}
+  ...   
+}
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87644">87644</a>
+Control access rules severity
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88625">88625</a>
+[1.5][compiler] Invalid Enum comparing (Build id: I20050219-1500)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87998">87998</a>
+[1.5][compiler] Enum constants generate warnings about synthetic constructor access
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88562">88562</a>
+Internal compiler error when compiling GNU Classpath
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88295">88295</a>
+[1.5][assist] too many completion on enum case label
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88446">88446</a>
+[1.5] annotations declared inside generic classes are not visible at runtime
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=54968">54968</a>
+[javadoc][select] ICodeAssist#codeSelect doesn't work for member references in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85379">85379</a>
+[1.5][select][enum] Code resolve on enum in switch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88429">88429</a>
+Redundant information in SourceMethodElementInfo
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88428">88428</a>
+Class file reader's method info still hold on byte array
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88223">88223</a>
+[1.5][compiler] Local enums are not reported as error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88224">88224</a>
+[1.5][DOM] ASTRewriteAnalyzer blows up with local enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86971">86971</a>
+[1.5][codeselect] F3 should perform if selecting '@Deprecated'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85713">85713</a>
+Signature.getTypeSignatureKind does not like wildcard types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87762">87762</a>
+[model] suspicious huge amount of IPackageFragmentRoot[]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88252">88252</a>
+Deleting a MemberValuePair with a NormalAnnotation child does not work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87818">87818</a>
+[compiler] local enums are illegal, but does this need to be a syntax error?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69657">69657</a>
+[dom] deprecate JLS2 once JLS3 is fully supported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81797">81797</a>
+NPE in SortElementBuilder
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80036">80036</a>
+EmptyStackException in CompilationUnitSorter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88187">88187</a>
+Unexpected deprecation warnings during full build
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88094">88094</a>
+[1.5] compiler accepts two methods with same erasure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86970">86970</a>
+[codeassist] Add an API on completion proposal API to surface the expected type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=88124">88124</a>
+More deprecated warnings than expected
+
+
+
+<a name="v_541"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 15th March 2005
+<br>Project org.eclipse.jdt.core v_541
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_541">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+
+<li>Compiler now recognizes <code>@Deprecated</code> annotations, and treats them equivalent
+to doc comment <code>/** @deprecated */</code>.
+</li>
+<li>Added optional compiler diagnosis to flag deprecated constructs missing a proper
+<code>@Deprecated</code> annotation (to encourage using annotations instead of doc comment tag).
+Corresponding problem IDs are: <code>IProblem.FieldMissingDeprecatedAnnotation</code>,
+<code>IProblem.MethodMissingDeprecatedAnnotation</code>,
+<code>IProblem.TypeMissingDeprecatedAnnotation</code>.
+<pre>
+* COMPILER / Reporting Missing @Deprecated Annotation
+*    When enabled, the compiler will issue an error or a warning whenever encountering a declaration
+*    carrying a @deprecated doc tag but has no corresponding @Deprecated annotation.
+*     - option id:        "org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"     
+</pre>
+</li>
+<li>JLS2 API have been deprecated (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69657">69657</a>).</li>
+<li>Allowed javadoc reference to varargs methods (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87845">87845</a>).<br>
+The 1.5 spec for the Javadoc tool does not mention the possibility
+of a variable arity indicator in method references. However, the 1.5
+Javadoc tool itself does indeed support it. Since it makes sense to have
+a way to explicitly refer to variable arity methods, it seems more likely
+that the Javadoc spec is wrong in this case.<br>
+Following API methods were added to <code>MethodRefParameter</code>:
+<pre>
+/**
+ * The "varargs" structural property of this node type (added in JLS3 API).
+ * @since 3.1
+ */
+public static final SimplePropertyDescriptor VARARGS_PROPERTY;
+/**
+ * Returns whether this method reference parameter is for
+ * the last parameter of a variable arity method (added in JLS3 API).
+ * <p>
+ * Note that the binding for the type <code>Foo</code>in the vararg method
+ * reference <code>#fun(Foo...)</code> is always for the type as 
+ * written; i.e., the type binding for <code>Foo</code>. However, if you
+ * navigate from the MethodRef to its method binding to the
+ * type binding for its last parameter, the type binding for the vararg
+ * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
+ * the way vararg methods get compiled.
+ * </p>
+ * 
+ * @return <code>true</code> if this is a variable arity parameter,
+ *    and <code>false</code> otherwise
+ * @exception UnsupportedOperationException if this operation is used in
+ * a JLS2 AST
+ * @since 3.1
+ */ 
+public boolean isVarargs();
+/**
+ * Sets whether this method reference parameter is for the last parameter of
+ * a variable arity method (added in JLS3 API).
+ * 
+ * @param variableArity <code>true</code> if this is a variable arity
+ *    parameter, and <code>false</code> otherwise
+ * @since 3.1
+ */ 
+public void setVarargs(boolean variableArity);
+</pre>
+</li>
+<li>Added new flags on nature of match to specify that declaring or return type should be ignored during the search
+(see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80264">80264</a>).<br>
+These flags are defined on <code>IJavaSearchConstants</code> interface:
+<pre>
+/**
+ * Ignore declaring type while searching result.
+ * Can be used in conjunction with any of the nature of match.
+ * @since 3.1
+ */
+int IGNORE_DECLARING_TYPE = 0x10;
+/**
+ * Ignore return type while searching result.
+ * Can be used in conjunction with any of the nature of match.
+ * Note that:
+ * 	- for fields search, pattern will ignore field type
+ * 	- this flag will have no effect for types search
+ * @since 3.1
+ */
+int IGNORE_RETURN_TYPE = 0x20;
+</pre>
+Note that these flags are active only for search of declarations (ie. <code>IJavaSearchConstants.DECLARATIONS</code> and <code>IJavaSearchConstants.ALL_OCCURRENCES</code>)
+and while searching for IJavaElement (see doc of <code>SearchPattern.createPattern(IJavaElement, int)</code> API method).
+</li>
+<li>Improved API for type name requestor. Abstract class <code>TypeNameRequestor</code> replaces interface <code>ITypeNameRequestor</code> which is deprecated.<br>
+There's now only a single method for type name requestor while accepting a type:
+<pre>
+/**
+ * Accepts a top-level or a member type.
+ *
+ * The default implementation of this method does nothing.
+ * Subclasses should override.
+ *
+ * @param modifiers the modifier flags of the type. Note that for source type,
+ *	these flags may slightly differ from thoses get after resolution.
+ *	For example an interface defined by <code>interface A {}</code>, although obviously public,
+ *	will be returned false by <code>Flags.isPublic(modifiers)</code> due to the fact
+ *	that its declaration does not explicitely define <code>public</code> flag.
+ *	@see org.eclipse.jdt.core.Flags
+ * @param packageName the dot-separated name of the package of the type
+ * @param simpleTypeName the simple name of the type
+ * @param enclosingTypeNames if the type is a member type, 
+ *	the simple names of the enclosing types from the outer-most to the
+ *	direct parent of the type (for example, if the class is x.y.A$B$C then
+ *	the enclosing types are [A, B]. This is an empty array if the type
+ *	is a top-level type.
+ * @param path the full path to the resource containing the type. If the resource is a .class file
+ *	or a .java file, this is the full path in the workspace to this resource. If the
+ *	resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated
+ *	by <code>IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR</code>: 
+ *	the first path is the full OS path to the archive (if it is an external archive), 
+ *	or the workspace relative <code>IPath</code> to the archive (if it is an internal archive), 
+ *	the second path is the path to the resource inside the archive.
+ */
+public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path)
+</pre>
+Clients can now distinguish Annotation, Enum, Interface and Class using <code>Flags</code> API methods on <code>modifiers</code> parameter.
+</li>
+<li>Added support for package-info.java. This allows to define annotations on the package declaration. See bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86167">86167</a> for 
+further details.</li>
+<li>Added API <code>JavaCore#newProjectEntry(IPath, IPath[], IPath[], boolean, IClasspathAttribute[], boolean)</code>
+      that take a 'combineAccessRestrictions' flag to control whether access restrictions of exported libraries of the project
+      should be combined with the access restrictions of this project entry.
+</li>
+<li>Added API method <code>AST#newName(String qualifiedName)</code> for creating 
+<code>SimpleName</code> or <code>QualifiedName</code>
+nodes depending on the form of the given name string.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83643">83643</a>
+[1.5] @Deprecated members not 'slashed'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86291">86291</a>
+[1.5][compiler] Annotation attribute see members of the annotated type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=69657">69657</a>
+[dom] deprecate JLS2 once JLS3 is fully supported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77349">77349</a>
+[compiler] ClassFormatError when accessing clone() or finalize() methods from an interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87956">87956</a>
+compiling error on jdk1.5 collection generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87900">87900</a>
+Error 'Requesting Java AST from selection': Bug in the Java AST parser
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87754">87754</a>
+[1.5][javadoc][dom] Type of ArrayType component type inside MethodRef has no binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87845">87845</a>
+[1.5][dom][javadoc] allow javadoc references to vararg methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87778">87778</a>
+[search] doesn't find all declarations of method with covariant return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80264">80264</a>
+[search] Search for method declarations in workspace, disregarding declaring type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85924">85924</a>
+[1.5][compiler[ code generation error in M5 w/regard to generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87849">87849</a>
+[AST] SimpleName.setIdentifier() not detecting bogus identifiers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86779">86779</a>
+AST#resolveWellKnownType(..) should support primitive type wrappers
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85900">85900</a>
+[1.5] [compiler] internal compiler reports name clash
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87777">87777</a>
+Bindings.isEqualTo returns false for equal bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86902">86902</a>
+[1.5][compiler] Raw field access is not flagged as unsafe type operation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81498">81498</a>
+[search] ITypeNameRequestor should support enums and annotations as well
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87490">87490</a>
+Internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85491">85491</a>
+[1.5] Compiler rejects autoboxing-calls to overloaded varargs methods as ambiguous
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87613">87613</a>
+Access restrictions should only apply to project's own package fragment roots
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86167">86167</a>
+[1.5] Add support for package-info.java
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87350">87350</a>
+IllegalArgumentException when converting AST with invalid enum body declaration
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85262">85262</a>
+[1.5] Bound mismatch: type R is not a valid substitute for the bounded parameter...
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87498">87498</a>
+StackOverflowError when marking occurrences of Comparable in Collections.min(..)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87481">87481</a>
+[1.5] type reference in CastExpression is generic type instead of parameterized
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87463">87463</a>
+The built-in Eclipse compiler behaves differently than IBM or Sun JDK
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85226">85226</a>
+[1.5] EnumConstantDeclaration should declare resolveConstructorBinding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=36938">36938</a>
+[plan item][1.5] Add early support for J2SE 1.5 features
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87404">87404</a>
+[javadoc] Unexpected not defined warning on constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85811">85811</a>
+BindingKey.toSignature should return method signature for methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87411">87411</a>
+[dom] API: ast.newName(String qualifiedName)
+	  	
+<a name="v_540"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 8th March 2005
+<br>Project org.eclipse.jdt.core v_540
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_540">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=83693">83693</a>
+[search][javadoc] References to methods/constructors: range does not include parameter lists
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87273">87273</a>
+[1.5][compiler] Code with generics compiles, but throws a NoSuchMethodError when executed
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87050">87050</a>
+ASTParser#createASTs(..) cannot resolve method type parameter binding from key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83002">83002</a>
+[1.5] Compiler generates incorrect signature for throws clause.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87318">87318</a>
+[1.5][compiler] Array.asList(int[]) should be accepted
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87171">87171</a>
+Find declaring node doesn't work for methods/fields using type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86908">86908</a>
+Code formatter fails to format when this code is present
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86967">86967</a>
+[1.5][dom] NPE in BindingKeyResolver for multi-level parameterized type binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86898">86898</a>
+[1.5][compiler] compiler should flag unchecked cast
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87267">87267</a>
+[1.5][compiler] cast from Integer[] to int[] should fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82830">82830</a>
+AST: String concatenation represented as single node
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83393">83393</a>
+[1.5][javadoc] reference to vararg method also considers non-array type as correct
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83285">83285</a>
+[javadoc] Javadoc reference to constructor of secondary type has no binding / not found by search
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=87042">87042</a>
+Passing null as first vararg makes parameter null (3.1M4)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86906">86906</a>
+[1.5][dom] SourceType#createField fails for enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86878">86878</a>
+Parameterized varargs causes Java formatter to fail
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80221">80221</a>
+[dom][javadoc] No Javadoc comment node when return type missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86901">86901</a>
+[1.5][search] Static import method references not found in unused import
+
+<a name="v_539"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 1st March 2005
+<br>Project org.eclipse.jdt.core v_539
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_539">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83319">bug 83319</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Added optional compiler diagnosis to flag incomplete enum switch statements.
+Corresponding problem ID is: <code>IProblem.MissingEnumConstantCase</code>
+<pre>
+* COMPILER / Reporting Incomplete Enum Switch
+*    When enabled, the compiler will issue an error or a warning whenever an enum constant has
+*    no corresponding case label in an enum switch statement
+*    type has no case label matching an enum constant.
+*     - option id:        "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"
+</pre>
+</li>
+<li>Added API <code>org.eclipse.jdt.core.dom.CompilationUnit#getJavaElement()</code> to retrieve the compilation unit
+     or class file the compilation unit node was created from.
+</li>
+<li>Added API <code>IMethodBinding#isSubsignature(IMethodBinding)</code> to find out if a method's signature 
+     is a subsignature of another method.
+</li>
+<li>Added optional compiler diagnosis to flag method overriding a superclass method, but missing 
+proper <code>@Override</code> annotation.
+Corresponding problem ID is: <code>IProblem.MissingOverrideAnnotation</code>
+
+<pre>
+* COMPILER / Reporting Missing @Override Annotation
+*    When enabled, the compiler will issue an error or a warning whenever encountering a method
+*    declaration which overrides a superclass method but has no @Override annotation.
+*     - option id:        "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "ignore"                               
+</pre>
+</li>
+<li>New CodeAssist feature: Enum constant are proposed inside switch label if the expression is an enum.
+<pre>
+Colors c;
+swith(c) {
+  case BLUE:
+  case RED&lt;complete here&gt;
+}
+</pre>
+</li>
+<li>New CodeAssist feature: Annotation's attribute name are proposed.
+<pre>
+@Annot(attr&lt;complete here&gt;=value)
+</pre>
+To propose this new completion kind a new API has been added: CompletionProposal.ANNOTATION_ATTRIBUTE_REF.<br>
+<pre>
+/**
+ * Completion is a reference to annotation's attribute.
+ * This kind of completion might occur in a context like
+ * &lt;code&gt;"@Annot(attr^=value)"&lt;/code&gt; and complete it to
+ * &lt;code&gt;"@Annot(attribute^=value)"&lt;/code&gt;.
+ * &lt;p&gt;
+ * The following additional context information is available
+ * for this kind of completion proposal at little extra cost:
+ * &lt;ul&gt;
+ * &lt;li&gt;{@link #getDeclarationSignature()} -
+ * the type signature of the annotation that declares the attribute that is referenced
+ * &lt;/li&gt;
+ * &lt;li&gt;{@link #getFlags()} -
+ * the modifiers flags of the attribute that is referenced
+ * &lt;/li&gt;
+ * &lt;li&gt;{@link #getName()} -
+ * the simple name of the attribute that is referenced
+ * &lt;/li&gt;
+ * &lt;li&gt;{@link #getSignature()} -
+ * the type signature of the attribute's type (as opposed to the
+ * signature of the type in which the referenced attribute
+ * is declared)
+ * &lt;/li&gt;
+ * &lt;/ul&gt;
+ * &lt;/p&gt;
+ * 
+ * @see #getKind()
+ */
+ public static final int ANNOTATION_ATTRIBUTE_REF = 13;
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83319">83319</a>
+[1.5][search] Search does not find references to statically imported methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86838">86838</a>
+[1.5] [compiler] Eclipse compiles parameterized code that javac says is "is not within its bound"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84121">84121</a>
+[1.5][search][varargs] reference to type reported as inaccurate in vararg
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83388">83388</a>
+[search] SearchRequestor reports 'null' as match
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86775">86775</a>
+[1.5][compiler] Infer Generic Types Arguments throws NPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86596">86596</a>
+[search] Search for type finds segments in import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79378">79378</a>
+[search] IOOBE when inlining a method
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68825">68825</a>
+[compiler][1.5] detect not-exhaustive enum switches
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81377">81377</a>
+[1.5][search] Semantics of search for methods with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84944">84944</a>
+[1.5][builder] Parameterized return type is sometimes not visible.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83770">83770</a>
+[1.5] ITypeBinding getQualifiedName doesn't cover the case of parameterized member type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84140">84140</a>
+The type binding of a vararg should be an array not a simple type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83100">83100</a>
+[5.0] need IVariableBinding.isGeneric/Parametrized, getGeneric..
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86663">86663</a>
+[DOM] AbortCompilation should not abort the creation of the tree
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86463">86463</a>
+[1.5][compiler] Compiler-Bug using generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85815">85815</a>
+[1.5] warn when raw iterator is used
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86611">86611</a>
+[1.4] 1.5 power double causes compiler internal failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86531">86531</a>
+Javadoc: class AST has several parameterless methods claiming to throw IllegalArgumentException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86217">86217</a>
+NPE resolving bounds of Type Variable
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84554">84554</a>
+[1.5] code assist in enum switch statements
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75702">75702</a>
+[dom] Need a way to get back from an AST to the originating ICompilationUnit
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86410">86410</a>
+formatting generics type parameters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86487">86487</a>
+[1.5] infinite loop in enhanced for statement when the current element is optimized out
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73676">73676</a>
+[dom] Need API on bindings for overriding and assignment rules
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72258">72258</a>
+[model] Should be able to dynamicaly set the size of Java model cache
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84562">84562</a>
+[DCR][1.5][options] Optional warning/error to avoid accidental overrides with JDK 5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85538">85538</a>
+[1.5] compiler does not reject cyclic annotation element types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86141">86141</a>
+[recovery] ClassCastException with annotation of parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=86179">86179</a>
+[1.5] Type parameters lost with nested inheritance and generics
+
+<a name="v_538"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M6 - 22nd February 2005
+<br>Project org.eclipse.jdt.core v_538
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_538">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Inclusion/exclusion filters used as import restrictions have been renamed into 'accessible files' and 'non accessible files' patterns.
+     The following APIs have been added on <code>IClasspathEntry</code>: <code>getAccessibleFiles()</code> and <code>getNonAccessibleFiles()</code>.
+     These are valid only for library, project, container and variable entries. <code>getInclusionPatterns()</code> and <code>getExclusionPatterns()</code> 
+     temporary return the accessible files and non accessible files patterns for these entries.
+</li>
+<li>Added ability to associate classpath attributes to a classpath entry (see <code>IClasspathAttribute</code>). A classpath attribute
+     is created using <code>JavaCore#newClasspathAttribute(String, String)</code>. Then one can associate this attribute with 
+     a classpath entry using one of:
+     <ul>
+     <li><code>JavaCore#newContainerEntry(IPath containerPath, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     <li><code>JavaCore#newLibraryEntry(IPath path, IPath sourceAttachmentPath, IPath sourceAttachmentRootPath, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     <li><code>JavaCore#newProjectEntry(IPath path, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     <li><code>JavaCore#newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation, IClasspathAttribute[] extraAttributes)</code></li>
+     <li><code>JavaCore#newVariableEntry(IPath variablePath, IPath variableSourceAttachmentPath, IPath variableSourceAttachmentRootPath, IPath[] accessibleFiles, IPath[] nonAccessibleFiles, IClasspathAttribute[] extraAttributes, boolean isExported)</code></li>
+     </ul>
+</li>
+<li>Added optional compiler diagnosis when a type parameter declaration is hiding another type.
+Corresponding problem ID is: <code>IProblem.TypeParameterHidingType</code>
+<pre>
+* COMPILER / Reporting Type Parameter Declaration Hiding another Type
+*    When enabled, the compiler will issue an error or a warning whenever a type parameter
+*    declaration is hiding some type.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.typeParameterHiding"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+<li>The predicates <code>isInterface()</code> on Java element and DOM AST are now answering <code>true</code>
+for annotation types. Indeed, annotation types are allowed to be implemented just like regular interfaces.
+</li>
+<li>Added optional compiler diagnosis signalling usage of an annotation type as a super interface.
+Corresponding problem ID is: <code>IProblem.AnnotationTypeUsedAsSuperInterface</code>
+<pre>
+* COMPILER / Reporting Use of Annotation Type as Super Interface
+*    When enabled, the compiler will issue an error or a warning whenever an annotation type is used
+*    as a super-interface. Though legal, this is discouraged.
+*     - option id:         "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"
+*     - possible values:   { "error", "warning", "ignore" }
+*     - default:           "warning"
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=72704">72704</a>
+[compiler][1.5] unexpected IBindings and class files with conflicting method argument types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85397">85397</a>
+[1.5][enum] erroneous strictfp keyword on enum type produces error on constructor
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83321">83321</a>
+[1.5][assist][enum] no override completion proposals in type when followed by a package visible enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85402">85402</a>
+[1.5][assist] NPE while trying to complete on empty annotation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85290">85290</a>
+[1.5] Code assist for annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85810">85810</a>
+[1.5][search] Missed type parameter reference in implements clause
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85421">85421</a>
+[1.5][search] NPE while searching type parameter reference in workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85432">85432</a>
+Make jdtcore.jar an executable jar
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85933">85933</a>
+Type parameters in anonymous type is missing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82429">82429</a>
+[1.5] Need emulation of Unicode 4 using 1.4 libraries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85062">85062</a>
+[compiler] Implicit static method invocation should target the receiver type not the declaring class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84355">84355</a>
+[1.5] Generics bounds overzealous when converting to Object
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85477">85477</a>
+[1.5] certain unchecked conversion not reported
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85303">85303</a>
+[1.5] wrong declaring class for invokevirtual call
+
+
+<a name="v_537"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 15th February 2005 - 3.1 MILESTONE 5
+<br>Project org.eclipse.jdt.core v_537
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_537">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=85203">85203</a>
+VerifyError running o.e.pdu.ui from workspace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85160">85160</a>
+[compiler] java.lang.Object.finalize() method cannot be invoked on an array type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85157">85157</a>
+[compiler] Integer[] is not compatible with String[] in conditional expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85215">85215</a>
+[DOM][1.5] Annotation type getModifiers() always returns 0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85115">85115</a>
+[1.5] AST annotation.isTopLevel() doesn't work
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84724">84724</a>
+[5.0][search] fails to find call sites for varargs constructors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=85125">85125</a>
+When bracket is placed after MethodDeclarator, build fails.
+
+<a name="v_536"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 14th February 2005
+<br>Project org.eclipse.jdt.core v_536
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_536">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=78906">78906</a>
+[1.5][compiler] this$0 is not allowed as a field in a member class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79396">79396</a>
+[compiler] Static receiver for a static method invocation should be generated to cover side-effects
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84801">84801</a>
+Bad code generated for Java 5.0
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83902">83902</a>
+[1.5] AbstractMethodError when using covariant returns
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83901">83901</a>
+[1.5] AbstractMethodError: Compiler fails to catch missing methods of implemented interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82461">82461</a>
+[5.0] Unconventional formatting of annotations in ASTRewrite
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81244">81244</a>
+error range for generic vararg argument
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84743">84743</a>
+[1.5][compiler] Cast between two interfaces doesn't need to check compatibility of method return types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84869">84869</a>
+Missing constant for "org.eclipse.jdt.core.compiler.problem.autoboxing"
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84770">84770</a>
+Formatter fails in specific case (.class in code)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84778">84778</a>
+NaiveASTFlattener should add spaces around extendedOperands in InfixExpression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84791">84791</a>
+[1.5][compiler] eclipse doesn't allow types to be derived from annotation types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83600">83600</a>
+[code assist] METHOD_REF proposals have non-standard signatures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80630">80630</a>
+[1.5] Conditional expression unboxing  should handle this case
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84717">84717</a>
+Typo in javadoc of Signature.C_GENERIC_END
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84528">84528</a>
+Not visiting line comments in compilation unit?
+	  	
+<a name="v_535"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 8th February 2005
+<br>Project org.eclipse.jdt.core v_535
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_535">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li> Tuned generic method type argument inference (JLS 15.12.2.7&amp;8).
+</li>
+<li> Optional diagnosis for assignment with no effect now also detects: "var = var++;" scenario.
+<li>Added APIs <code>IType#getKey()</code>, <code>IField#getKey()</code>, <code>IMethod#getKey()</code>
+    that return a binding key for these Java elements.
+</li>
+<li>Added APIs <code>IType#isResolved()</code>, <code>IField#isResolved()</code>, 
+    <code>IMethod#isResolved()</code> that return whether these Java elements are resolved elements
+    and thus whether their key (see above) contains resolved information.
+</li>
+<li>Added API class <code>org.eclipse.jdt.core.BindingKey</code> to decode a binding key
+    obtained from <code>IBinding#getKey()</code> or one of the <code>getKey()</code> methods above.
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84717">84717</a>
+Typo in javadoc of Signature.C_GENERIC_START
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84669">84669</a>
+[5.0] VerifyError: Expecting to find object/array on stack
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84593">84593</a>
+[1.5][compiler] NPE during problem detection with raw reference to parameterized inner class
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84558">84558</a>
+Strange error message when using keywords "const" and "goto" as variable names
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83648">83648</a>
+[1.5] Enum constructor cannot be public or protected
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83379">83379</a>
+[1.5] compiler does not warn when overriding methods with parameters as array and vararg
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84345">84345</a>
+[1.5][compiler] Widening reference is possible when boxing in a cast expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83615">83615</a>
+[1.5][compiler] lenient subclass checking with interdependent type variables
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84480">84480</a>
+Warning for "no effect assignment" j = j++
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83500">83500</a>
+Can't restore a secondary top level from key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84416">84416</a>
+Stepping into message send without receiver should highlight message before sending message
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76773">76773</a>
+Stepping through conditional looks like it evaluates both halves
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84504">84504</a>
+[Format] Extra empty line before class in default package when imports are specified
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83383">83383</a>
+IllegalArgumentException in Signature.getParameterCount
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83218">83218</a>
+[1.5] Covariant return type &amp; generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83499">83499</a>
+NPE when restoring ITypeBinding from key
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83611">83611</a>
+compiler reports error but there is no error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84055">84055</a>
+[1.5] Unnecessary cast  wrongly reported with boxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83965">83965</a>
+[1.5][compiler] Widening conversion is possible when unboxing in a cast expression
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81544">81544</a>
+[dom] java.util.List&lt;URL&gt; sometimes has a binding, sometimes not
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82647">82647</a>
+[compiler][1.5] Erroneous error with autoboxing and conditional operand
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79696">79696</a>
+[dom] Wrong type binding in qualified name
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84215">84215</a>
+ArrayIndexOutOfBoundsException, internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84181">84181</a>
+[1.5] ITypeBinding.isFromSource incorrect on raw bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83376">83376</a>
+[1.5] compiler should error on ambiguous method invocation due to duplicate static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78934">78934</a>
+[1.5][dom] ParameterizedType for nested generic types has missing bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83162">83162</a>
+Eclipse reports no name clash with equivalent bridge methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81332">81332</a>
+[1.5][compiler] Is this a name clash?
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80626">80626</a>
+[1.5] enum types cannot define a compareTo(Object o) method
+
+
+<a name="v_534"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 1st February 2005
+<br>Project org.eclipse.jdt.core v_534
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_534">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Add CompletionProposal#getDeclaringKey() and CompletionProposal#getKey() API
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84064">84064</a>
+AST: Wrong source ranges for superconstructorinv with type args
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83939">83939</a>
+[1.5][compiler] null is allowed as a legal element value in annotations
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83817">83817</a>
+IBinding#isEqualTo(..) returns true for methods of different parameterized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82349">82349</a>
+[compiler][1.5] Problems deriving from generic class that uses inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83904">83904</a>
+[compiler][1.5] Y&lt;T&gt; should be uniquely defined in the same signature
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83646">83646</a>
+NPE renaming package
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83398">83398</a>
+[compiler][1.5] compiler allows adding Object to List<? super Number>
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83219">83219</a>
+NPE in ProblemReporter with duplicate abstract enum methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83860">83860</a>
+[1.5] java.lang.VerifyError with Enums
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83847">83847</a>
+[compiler][1.5] can create annonymous class of an enum
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83236">83236</a>
+ClassCastException using code assist in a javadoc comment
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83822">83822</a>
+Classes at root of project not found in Open Type dialog
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83593">83593</a>
+Rename of enum type does not update constructor / throws ClassCastException
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83225">83225</a>
+[1.5] incorrect(?) compiler errors with type inference
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83127">83127</a>
+[1.5][javadoc][dom] Wrong / strange bindings for references in javadoc to methods with type variables as parameter types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80257">80257</a>
+[1.5][javadoc][dom] Type references in javadocs should have generic binding, not raw
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83713">83713</a>
+[search] IAE while searching reference to parameterized type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83684">83684</a>
+[formatting] Formatting codes like A extends B.C&lt;Object&gt; has no effect.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83599">83599</a>
+CU dirty after move refactoring
+
+
+<a name="v_533"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 25th January 2005
+<br>Project org.eclipse.jdt.core v_533
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_533">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Search engine is now able to find references and declarations to ITypeParameter.<br>
+To perform this kind of search, clients need to create a pattern using <code>SearchPattern.createPattern(IJavaElement,int,int)</code>
+providing searched ITypeParameter for IJavaElement parameter.
+</li>
+<li><code>TypeParameter#resolveBinding()</code> now returns an <code>ITypeBinding</code> instead of
+     an <code>IBinding</code></li>
+<li>Java model operations have been ported off the deprecated JDOM. They now use AST rewrite. This enables
+     these operations on local and anonymous types, enumerations and annotation types.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83489">83489</a>
+[select] Code select returns IType instead of ITypeParameter on method parameters types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83536">83536</a>
+"Incompatible argument to function" at vararg function
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83300">83300</a>
+[1.5] ClassCastException in #getJavaElement() on binding of annotation element
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81190">81190</a>
+[1.5][search] no search for type parameters - SearchPattern is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82671">82671</a>
+[compiler][1.5]Protected field not visible to subclass in different package when having a class parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83210">83210</a>
+Unidentical ITypeBindings for same type from same AST from reconcile
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80800">80800</a>
+getErasure() of ITypeBinding and IMethodBinding don't match the JLS
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83304">83304</a>
+[1.5][search] Erasure match doesn't work for binary parameterized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83078">83078</a>
+Auto formating multiple classes has errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=25800">25800</a>
+Class file editor uses non-standard modifier order
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82859">82859</a>
+[1.5] void.class is incompatible with Void.TYPE
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83297">83297</a>
+[1.5] Annotation bindings don't provide their declared elements/methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=43483">43483</a>
+[model] Can not add method to local type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77894">77894</a>
+[model] Remove dependency to old JDOM in JavaModel implementation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83161">83161</a>
+Can't access public field from private subclass
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78151">78151</a>
+'Insert single proposals automatically' should not insert without prefix
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83096">83096</a>
+[1.5][compiler] NPE for class with duplicate type parameter
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82547">82547</a>
+[1.5][compiler] NullPointerException compiling invalid source
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83098">83098</a>
+IBinding#isEqualTo(..) does not compare occurrence count of local variables
+
+
+<a name="v_532"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 18th January 2005
+<br>Project org.eclipse.jdt.core v_532
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_532">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Support for generic methods/constructors search has been added to SearchEngine (see bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75642">75642</a>).<br>
+User can now search for declaration and/or references to generic methods/constructors or parameterized methods/constructors (like <code>public &lt;U&gt; void foo(U u){}</code> or <code>&lt;String&gt;foo("")</code> for example).
+This search can be done either selecting a JavaElement or using Java Search dialog.
+</li>
+<li>Added new API <code>JavaConventions#validateTypeVariableName(String)</code>.</li>
+<li>Added new API <code>JavaCore#newTypeHierarchy(IRegion,WorkingCopyOwner,IProgressMonitor)</code> that creates a hierarchy
+     independently of a project.</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83032">83032</a>
+VerifyError for anonymous declaration using variable arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=75642">75642</a>
+[1.5][search] Methods and constructor search does not work with generics
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83013">83013</a>
+[5.0] TypeDeclaration after AnnotationTypeDeclaration has wrong source range
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82985">82985</a>
+Static imports can't resolve bindings
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=83011">83011</a>
+[5.0] TypeName of an Annotation has no binding
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79144">79144</a>
+[1.5][compiler] generic type checking not performed for method return array types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82844">82844</a>
+[1.5] Array type as type variable bound gives internal compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81590">81590</a>
+[1.5][compiler] Iteration over nested arrays is broken
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82439">82439</a>
+[compiler] [1.5] internal compiler reports type mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80945">80945</a>
+[1.5] Code assist does not offer static fields and methods from static imports
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82590">82590</a>
+[compiler] [1.5]  internal compiler reports method not implemented
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81721">81721</a>
+[compiler][1.5] Correct use of generic interfaces give compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82754">82754</a>
+[1.5] too many methods allowed by static import
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80745">80745</a>
+[1.5][compiler] Two interfaces with methods with compatible return types are compatible
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80736">80736</a>
+[1.5] Compiler doesn't check that bounds have methods with same return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73535">73535</a>
+[1.5][model] Method to validate type parameter names missing in JavaConventions
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82740">82740</a>
+[assist] NPE inside CompletionEngine with 1.5 code if compliance source level is 1.4
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80098">80098</a>
+newTypeHierarchy(IRegion,...) should not be constrained to an IJavaProject
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82510">82510</a>
+[compiler] Util.bind(...) methods should use MessageFormat
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81706">81706</a>
+[1.5] Static import of static method produces compile error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82670">82670</a>
+[5.0] wrong source range for VariableDeclarationFragment with ArrayCreation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=80743">80743</a>
+[compiler] Interface cannot define a method from Object with a different return type
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82616">82616</a>
+CharacterLiteral.charValue fails for '\000'
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=77283">77283</a>
+Incremental and full builds produce different problem markers for same duplicate type error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74394">74394</a>
+[compiler] Provide XML output option for Eclipse compiler
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81719">81719</a>
+[compiler][1.5] Correct use of generic abstract classes give compiler error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81945">81945</a>
+[compiler] Enum and Duplicate case error
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82542">82542</a>
+Internal error during AST creation
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82558">82558</a>
+[select] Text selection fail on constructor when parameters are parameterized types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78232">78232</a>
+[1.5][generics]Erroneous warning implementing generic method from interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82504">82504</a>
+[compiler][1.5] ClassCastException when parsing a CastExpression between an array type and a type variable
+
+
+<a name="v_531"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.1M5 - 11th January 2005
+<br>Project org.eclipse.jdt.core v_531
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_531">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+<li>Added API <code>ASTParser#createBindings(IJavaElement[],IProgressMonitor)</code> to create the DOM bindings for the given 
+     Java elements.</li>
+<li>Fix for <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82004">bug 82004</a> required the index version to be incremented. 
+     Indexes will be automatically regenerated upon subsequent search queries (accounting for indexing notification in search progress dialogs).
+</li>
+<li>Merged problem <code>IProblem.UnnecessaryArgumentCast</code> with <code>IProblem.UnnecessaryCast</code> since it provided little additional value,
+and was rather perceived as confusing. From now on, only <code>IProblem.UnnecessaryCast</code> is reported.
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82514">82514</a>
+[1.5][javadoc] Problem with generics in javadoc
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82382">82382</a>
+IMethodBinding#getJavaElement() for method m(T t) in parameterized type Gen&lt;T&gt; is null
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81923">81923</a>
+In certain cases generics seens to be applied before autoboxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82250">82250</a>
+[5.0] don't allow duplicate interface bounds
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82432">82432</a>
+[1.5] VerifyError with Autoboxing
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82187">82187</a>
+[compiler] [1.5] internal compiler reports bound mismatch
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82159">82159</a>
+[compiler][1.5] Eclipse vs. javac: Differences when creating generic inner types
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81535">81535</a>
+[compiler] compliance 1.5 should work with source 1.4 on 1.5 libraries
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82137">82137</a>
+[select] Code resolve doesn't work on static imports [5.0]
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82102">82102</a>
+Should not compile related methods with different signatures but same erasures
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76761">76761</a>
+[model] ImportContainer.hasChildren() should not return true
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=79334">79334</a>
+[classpath] Build path info not updated properly
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82217">82217</a>
+[compiler][5.0] switch on enum allows non enum constants
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=73081">73081</a>
+Inconsistant type cast warning.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81856">81856</a>
+quote problems in property files (JDT)
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=68823">68823</a>
+[dom] Ctrl+C command fails when "assert" is enabled
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81824">81824</a>
+A generic interface is allowed to be implemented more than once - contrary to Java language specification
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81571">81571</a>
+Autoboxing ambiguousy
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81568">81568</a>
+[1.5][compiler] Covariant return types fails when an interface extends another interface
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82216">82216</a>
+IVariableBinding: Need to know if it is enum constant or normal var
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78520">78520</a>
+[model] IType#getSuperInterfaceTypeSignatures() doesn't include type arguments
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=82253">82253</a>
+[5.0] Signature#getSimpleName(String) inserts superfluous whitespace characters
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=78698">78698</a>
 [format] Space before ? should default to false
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=81063">81063</a>
 [model] Clarify the problem requestor paramter in becomeWorkingCopy
@@ -1139,8 +2610,6 @@
 Formatter fails on EnumDeclaration
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=74776">74776</a>
 [Search] Wrong search results for almost identical method
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=70827">70827</a>
-[Search] wrong reference match to private method of supertype
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=29865">29865</a>
 Source visibility in project dependency
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=76181">76181</a>
@@ -1458,6 +2927,7 @@
 <li>Added optional compiler diagnosis for usage of 'enum' as an identifier.
 Corresponding problem ID is IProblem.UseEnumAsAnIdentifier.
 </li>
+<li>
 <pre>
 * COMPILER / Reporting Usage of 'enum' Identifier
 *    When enabled, the compiler will issue an error or a warning whenever 'enum' is 
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index b74eb7b..b6fb7f7 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,9 +13,11 @@
 import java.util.Locale;
 import java.util.Map;
 
+import org.eclipse.jdt.core.CompletionContext;
 import org.eclipse.jdt.core.CompletionProposal;
 import org.eclipse.jdt.core.CompletionRequestor;
 import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAccessRule;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
@@ -30,6 +32,7 @@
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
 import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.env.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
@@ -44,9 +47,12 @@
 import org.eclipse.jdt.internal.core.BasicCompilationUnit;
 import org.eclipse.jdt.internal.core.INamingRequestor;
 import org.eclipse.jdt.internal.core.InternalNamingConventions;
+import org.eclipse.jdt.internal.core.SourceMethod;
+import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
 import org.eclipse.jdt.internal.core.SourceType;
 import org.eclipse.jdt.internal.core.BinaryTypeConverter;
 import org.eclipse.jdt.internal.core.SearchableEnvironment;
+import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
 
 /**
  * This class is the entry point for source completions.
@@ -60,7 +66,8 @@
 	public HashtableOfObject typeCache;
 	
 	public static boolean DEBUG = false;
-
+	public static boolean PERF = false;
+	
 	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
 	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
 	private final static char[] SEMICOLON = new char[] { ';' };
@@ -69,6 +76,7 @@
 	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
 	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
 	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
+	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
 	
 	private final static int SUPERTYPE = 1;
 	private final static int SUBTYPE = 2;
@@ -82,8 +90,11 @@
 	int expectedTypesFilter;
 	int uninterestingBindingsPtr = -1;
 	Binding[] uninterestingBindings = new Binding[1];
+	int forbbidenBindingsPtr = -1;
+	Binding[] forbbidenBindings = new Binding[1];
 	
 	boolean assistNodeIsClass;
+	boolean assistNodeIsEnum;
 	boolean assistNodeIsException;
 	boolean assistNodeIsInterface;
 	boolean assistNodeIsAnnotation;
@@ -241,244 +252,92 @@
 	}
 
 	/**
-	 * One result of the search consists of a new annotation.
+	 * One result of the search consists of a new type.
 	 *
 	 * NOTE - All package and type names are presented in their readable form:
 	 *    Package names are in the form "a.b.c".
 	 *    Nested type names are in the qualified form "A.I".
 	 *    The default package is represented by an empty array.
 	 */
-	public void acceptAnnotation(
+	public void acceptType(
 		char[] packageName,
-		char[] annotationName,
+		char[] typeName,
 		int modifiers,
 		AccessRestriction accessRestriction) {
 
-		char[] fullyQualifiedName = CharOperation.concat(packageName, annotationName, '.');
+		char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
 		char[] completionName = fullyQualifiedName;
 
 		if (this.knownTypes.containsKey(completionName)) return;
 
 		this.knownTypes.put(completionName, this);
 
-		if(this.options.checkRestrictions && accessRestriction != null) return;
+		int accessibility = IAccessRule.K_ACCESSIBLE;
+		if(accessRestriction != null) {
+			switch (accessRestriction.getProblemId()) {
+				case IProblem.ForbiddenReference:
+					if(this.options.checkForbiddenReference) return;
+					accessibility = IAccessRule.K_NON_ACCESSIBLE;
+					break;
+				case IProblem.DiscouragedReference:
+					if(this.options.checkDiscouragedReference) return;
+					accessibility = IAccessRule.K_DISCOURAGED;
+					break;
+			}
+		}
 		
 		boolean isQualified = true;
 		int relevance = computeBaseRelevance();
 		relevance += computeRelevanceForInterestingProposal();
-		relevance += computeRelevanceForRestrictions(accessRestriction != null);
+		relevance += computeRelevanceForRestrictions(accessibility);
 		if (this.resolvingImports) {
 			completionName = CharOperation.concat(completionName, new char[] { ';' });
 			relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
 		} else {
-			if (mustQualifyType(packageName, annotationName)) {
+			if (mustQualifyType(packageName, typeName)) {
 				if (packageName == null || packageName.length == 0)
 					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
 						return; // ignore types from the default package from outside it
 			} else {
-				completionName = annotationName;
+				completionName = typeName;
 				isQualified = false;
 			}
-			relevance += computeRelevanceForCaseMatching(this.completionToken, annotationName);
-			relevance += computeRelevanceForExpectingType(packageName, annotationName);
-			relevance += computeRelevanceForAnnotation();
+			relevance += computeRelevanceForCaseMatching(this.completionToken, typeName);
+			relevance += computeRelevanceForExpectingType(packageName, typeName);
 			relevance += computeRelevanceForQualification(isQualified);
+			
+			int kind = modifiers & (IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation);
+			switch (kind) {
+				case IConstants.AccAnnotation:
+				case IConstants.AccAnnotation | IConstants.AccInterface:
+					relevance += computeRelevanceForAnnotation();
+					relevance += computeRelevanceForInterface();
+					break;
+				case IConstants.AccEnum:
+					relevance += computeRelevanceForEnum();
+					break;
+				case IConstants.AccInterface:
+					relevance += computeRelevanceForInterface();
+					break;
+				default:
+					relevance += computeRelevanceForClass();
+					relevance += computeRelevanceForException(typeName);
+					break;
+			}
 		}
 		
 		this.noProposal = false;
 		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
 			CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
 			proposal.setDeclarationSignature(packageName);
-			proposal.setSignature(createNonGenericTypeSignature(packageName, annotationName));
+			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
 			proposal.setPackageName(packageName);
-			proposal.setTypeName(annotationName);
-			proposal.setCompletion(completionName);
-			proposal.setFlags(modifiers | Flags.AccInterface | Flags.AccAnnotation);
-			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-			proposal.setRelevance(relevance);
-			this.requestor.accept(proposal);
-			if(DEBUG) {
-				this.printDebug(proposal);
-			}
-		}
-	}
-	
-	/**
-	 * One result of the search consists of a new class.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.M".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptClass(char[] packageName, char[] className, int modifiers, AccessRestriction accessRestriction) {
-
-		char[] fullyQualifiedName = CharOperation.concat(packageName, className, '.');
-		char[] completionName = fullyQualifiedName;
-		
-		if (this.knownTypes.containsKey(completionName)) return;
-
-		this.knownTypes.put(completionName, this);
-		
-		if(this.options.checkRestrictions && accessRestriction != null) return;
-		
-		boolean isQualified = true;
-		int relevance = computeBaseRelevance();
-		relevance += computeRelevanceForInterestingProposal();
-		relevance += computeRelevanceForRestrictions(accessRestriction != null);
-		if (this.resolvingImports) {
-			completionName = CharOperation.concat(completionName, SEMICOLON);
-			relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
-		} else {
-			if (mustQualifyType(packageName, className)) {
-				if (packageName == null || packageName.length == 0)
-					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
-						return; // ignore types from the default package from outside it
-			} else {
-				completionName = className;
-				isQualified = false;
-			}
-			relevance += computeRelevanceForCaseMatching(this.completionToken, className);
-			relevance += computeRelevanceForExpectingType(packageName, className);
-			relevance += computeRelevanceForClass();
-			relevance += computeRelevanceForException(className);
-			relevance += computeRelevanceForQualification(isQualified);
-		}
-
-		this.noProposal = false;
-		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-			CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-			proposal.setDeclarationSignature(packageName);
-			proposal.setSignature(createNonGenericTypeSignature(packageName, className));
-			proposal.setPackageName(packageName);
-			proposal.setTypeName(className);
+			proposal.setTypeName(typeName);
 			proposal.setCompletion(completionName);
 			proposal.setFlags(modifiers);
 			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
 			proposal.setRelevance(relevance);
-			this.requestor.accept(proposal);
-			if(DEBUG) {
-				this.printDebug(proposal);
-			}
-		}
-	}
-	
-	/**
-	 * One result of the search consists of a new enum.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.M".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptEnum(char[] packageName, char[] enumName, int modifiers, AccessRestriction accessRestriction) {
-
-		char[] fullyQualifiedName = CharOperation.concat(packageName, enumName, '.');
-		char[] completionName = fullyQualifiedName;
-		
-		if (this.knownTypes.containsKey(completionName)) return;
-
-		this.knownTypes.put(completionName, this);
-		
-		if(this.options.checkRestrictions && accessRestriction != null) return;
-		
-		boolean isQualified = true;
-		int relevance = computeBaseRelevance();
-		relevance += computeRelevanceForInterestingProposal();
-		relevance += computeRelevanceForRestrictions(accessRestriction != null);
-		if (this.resolvingImports) {
-			completionName = CharOperation.concat(completionName, SEMICOLON);
-			relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
-		} else {
-			if (mustQualifyType(packageName, enumName)) {
-				if (packageName == null || packageName.length == 0)
-					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
-						return; // ignore types from the default package from outside it
-			} else {
-				completionName = enumName;
-				isQualified = false;
-			}
-			relevance += computeRelevanceForCaseMatching(this.completionToken, enumName);
-			relevance += computeRelevanceForExpectingType(packageName, enumName);
-			relevance += computeRelevanceForClass();
-			relevance += computeRelevanceForException(enumName);
-			relevance += computeRelevanceForQualification(isQualified);
-		}
-
-		this.noProposal = false;
-		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-			CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-			proposal.setDeclarationSignature(packageName);
-			proposal.setSignature(createNonGenericTypeSignature(packageName, enumName));
-			proposal.setPackageName(packageName);
-			proposal.setTypeName(enumName);
-			proposal.setCompletion(completionName);
-			proposal.setFlags(modifiers | Flags.AccEnum);
-			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-			proposal.setRelevance(relevance);
-			this.requestor.accept(proposal);
-			if(DEBUG) {
-				this.printDebug(proposal);
-			}
-		}
-	}
-	
-	/**
-	 * One result of the search consists of a new interface.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.I".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptInterface(
-		char[] packageName,
-		char[] interfaceName,
-		int modifiers,
-		AccessRestriction accessRestriction) {
-
-		char[] fullyQualifiedName = CharOperation.concat(packageName, interfaceName, '.');
-		char[] completionName = fullyQualifiedName;
-
-		if (this.knownTypes.containsKey(completionName)) return;
-
-		this.knownTypes.put(completionName, this);
-
-		if(this.options.checkRestrictions && accessRestriction != null) return;
-		
-		boolean isQualified = true;
-		int relevance = computeBaseRelevance();
-		relevance += computeRelevanceForInterestingProposal();
-		relevance += computeRelevanceForRestrictions(accessRestriction != null);
-		if (this.resolvingImports) {
-			completionName = CharOperation.concat(completionName, new char[] { ';' });
-			relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName);
-		} else {
-			if (mustQualifyType(packageName, interfaceName)) {
-				if (packageName == null || packageName.length == 0)
-					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
-						return; // ignore types from the default package from outside it
-			} else {
-				completionName = interfaceName;
-				isQualified = false;
-			}
-			relevance += computeRelevanceForCaseMatching(this.completionToken, interfaceName);
-			relevance += computeRelevanceForExpectingType(packageName, interfaceName);
-			relevance += computeRelevanceForInterface();
-			relevance += computeRelevanceForQualification(isQualified);
-		}
-		
-		this.noProposal = false;
-		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-			CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-			proposal.setDeclarationSignature(packageName);
-			proposal.setSignature(createNonGenericTypeSignature(packageName, interfaceName));
-			proposal.setPackageName(packageName);
-			proposal.setTypeName(interfaceName);
-			proposal.setCompletion(completionName);
-			proposal.setFlags(modifiers | Flags.AccInterface);
-			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-			proposal.setRelevance(relevance);
+			proposal.setAccessibility(accessibility);
 			this.requestor.accept(proposal);
 			if(DEBUG) {
 				this.printDebug(proposal);
@@ -503,7 +362,7 @@
 		relevance += computeRelevanceForInterestingProposal();
 		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
 		relevance += computeRelevanceForQualification(true);
-		relevance += computeRelevanceForRestrictions(false);
+		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 		
 		this.noProposal = false;
 		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
@@ -522,17 +381,39 @@
 			}
 		}
 	}
-
-	private void complete(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+		
+	private void buildContext() {
+		CompletionContext context = new CompletionContext();
+		
+		// build expected types context
+		if (this.expectedTypesPtr > -1) {
+			int length = this.expectedTypesPtr + 1;
+			char[][] expTypes = new char[length][];
+			char[][] expKeys = new char[length][];
+			for (int i = 0; i < length; i++) {
+				expTypes[i] = getSignature(this.expectedTypes[i]);
+				expKeys[i] = this.expectedTypes[i].computeUniqueKey();
+			}
+			context.setExpectedTypesSignatures(expTypes);
+			context.setExpectedTypesKeys(expKeys);
+		}
+		
+		this.requestor.acceptContext(context);
+	}
+	
+	private void complete(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) {
 
 		setSourceRange(astNode.sourceStart, astNode.sourceEnd);
 		
+		scope = computeForbiddenBindings(astNode, astNodeParent, scope);
 		computeUninterestingBindings(astNodeParent, scope);
 		if(astNodeParent != null) {
 			if(!isValidParent(astNodeParent, astNode, scope)) return;
 			computeExpectedTypes(astNodeParent, astNode, scope);
 		}
 		
+		buildContext();
+		
 		if (astNode instanceof CompletionOnFieldType) {
 
 			CompletionOnFieldType field = (CompletionOnFieldType) astNode;
@@ -541,11 +422,17 @@
 			setSourceRange(type.sourceStart, type.sourceEnd);
 			
 			findTypesAndPackages(this.completionToken, scope);
-			findKeywordsForMember(this.completionToken, field.modifiers);
+			if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+				findKeywordsForMember(this.completionToken, field.modifiers);
+			}
 			
 			if(!field.isLocalVariable && field.modifiers == CompilerModifiers.AccDefault) {
-				findMethods(this.completionToken,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false,false,true);
-				proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+				if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+					findMethods(this.completionToken,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false,false,true);
+				}
+				if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+				}
 			}
 		} else {
 			if(astNode instanceof CompletionOnMethodReturnType) {
@@ -555,32 +442,59 @@
 				this.completionToken = type.token;
 				setSourceRange(type.sourceStart, type.sourceEnd);
 				findTypesAndPackages(this.completionToken, scope.parent);
-				findKeywordsForMember(this.completionToken, method.modifiers);
+				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+					findKeywordsForMember(this.completionToken, method.modifiers);
+				}
 			
 				if(method.modifiers == CompilerModifiers.AccDefault) {
-					findMethods(this.completionToken,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false,false,true);
-					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+					if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+						findMethods(this.completionToken,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false,false,true);
+					}
+					if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+						proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+					}
 				}
 			} else {
 				
 				if (astNode instanceof CompletionOnSingleNameReference) {
 					CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
 					this.completionToken = singleNameReference.token;
-					findVariablesAndMethods(
-						this.completionToken,
-						scope,
-						(CompletionOnSingleNameReference) astNode,
-						scope);
-					// can be the start of a qualified type name
-					findTypesAndPackages(this.completionToken, scope);
-					findKeywords(this.completionToken, singleNameReference.possibleKeywords);
-					if(singleNameReference.canBeExplicitConstructor){
-						if(CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
-							ReferenceBinding ref = scope.enclosingSourceType();
-							findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
-						} else if(CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
-							ReferenceBinding ref = scope.enclosingSourceType();
-							findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
+					SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
+					if(switchStatement != null
+							&& switchStatement.expression.resolvedType != null
+							&& switchStatement.expression.resolvedType.isEnum()) {
+						if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+							this.findEnumConstant(this.completionToken, (SwitchStatement) astNodeParent);
+						}
+					} else {
+						if(this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+							findTypesAndPackages(this.completionToken, scope);
+						} else {
+							findVariablesAndMethods(
+								this.completionToken,
+								scope,
+								singleNameReference,
+								scope,
+								insideTypeAnnotation,
+								singleNameReference.isInsideAnnotationAttribute);
+							// can be the start of a qualified type name
+							findTypesAndPackages(this.completionToken, scope);
+							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+								if(this.completionToken != null && this.completionToken.length != 0) {
+									findKeywords(this.completionToken, singleNameReference.possibleKeywords);
+								} else {
+									findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
+								}
+							}
+							if(singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
+								if(CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
+									ReferenceBinding ref = scope.enclosingSourceType();
+									findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
+								} else if(CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
+									ReferenceBinding ref = scope.enclosingSourceType();
+									findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
+								}
+							}
 						}
 					}
 				} else {
@@ -590,6 +504,7 @@
 						this.completionToken = ((CompletionOnSingleTypeReference) astNode).token;
 						
 						this.assistNodeIsClass = astNode instanceof CompletionOnClassReference;
+						this.assistNodeIsEnum = this.assistNodeIsClass;
 						this.assistNodeIsException = astNode instanceof CompletionOnExceptionReference;
 						this.assistNodeIsInterface = astNode instanceof CompletionOnInterfaceReference;
 	
@@ -597,13 +512,15 @@
 						if (qualifiedBinding == null) {
 							findTypesAndPackages(this.completionToken, scope);
 							} else {
-								findMemberTypes(
-								this.completionToken,
-								(ReferenceBinding) qualifiedBinding,
-								scope,
-								scope.enclosingSourceType(),
-								false,
-								new ObjectVector());
+								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+									findMemberTypes(
+									this.completionToken,
+									(ReferenceBinding) qualifiedBinding,
+									scope,
+									scope.enclosingSourceType(),
+									false,
+									new ObjectVector());
+								}
 						}
 					} else {
 						
@@ -626,24 +543,29 @@
 							} else {
 	
 								if (qualifiedBinding instanceof ReferenceBinding) {
-	
+									boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
 									ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
 									setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
 	
-									findMemberTypes(this.completionToken, receiverType, scope, scope.enclosingSourceType(), false, new ObjectVector());
-	
-									findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
+									if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+										findMemberTypes(this.completionToken, receiverType, scope, scope.enclosingSourceType(), false, new ObjectVector());
+									}
+									if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+										findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
+									}
 									
 									MethodScope methodScope = null;
-									if((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
-										|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic)) {
+									if(!isInsideAnnotationAttribute &&
+											!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
+											((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
+											|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
 										if(this.completionToken.length > 0) {
 											findKeywords(this.completionToken, new char[][]{Keywords.THIS});
 										} else {
 											int relevance = computeBaseRelevance();
 											relevance += computeRelevanceForInterestingProposal();
 											relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
-											relevance += computeRelevanceForRestrictions(false); // no access restriction for keywords
+											relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
 											this.noProposal = false;
 											if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
 												CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
@@ -659,32 +581,36 @@
 										}
 									}
 	
-									findFields(
-										this.completionToken,
-										receiverType,
-										scope,
-										new ObjectVector(),
-										new ObjectVector(),
-										true,
-										ref,
-										scope,
-										false,
-										true);
+									if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+										findFields(
+											this.completionToken,
+											receiverType,
+											scope,
+											new ObjectVector(),
+											new ObjectVector(),
+											true,
+											ref,
+											scope,
+											false,
+											true);
+									}
 	
-									findMethods(
-										this.completionToken,
-										null,
-										receiverType,
-										scope,
-										new ObjectVector(),
-										true,
-										false,
-										false,
-										ref,
-										scope,
-										false,
-										false,
-										true);
+									if(!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+										findMethods(
+											this.completionToken,
+											null,
+											receiverType,
+											scope,
+											new ObjectVector(),
+											true,
+											false,
+											false,
+											ref,
+											scope,
+											false,
+											false,
+											true);
+									}
 	
 								} else {
 	
@@ -704,6 +630,7 @@
 								this.insideQualifiedReference = true;
 								
 								this.assistNodeIsClass = astNode instanceof CompletionOnQualifiedClassReference;
+								this.assistNodeIsEnum = this.assistNodeIsClass;
 								this.assistNodeIsException = astNode instanceof CompletionOnQualifiedExceptionReference;
 								this.assistNodeIsInterface = astNode instanceof CompletionOnQualifiedInterfaceReference;
 								
@@ -714,15 +641,16 @@
 	
 								// get the source positions of the completion identifier
 								if (qualifiedBinding instanceof ReferenceBinding) {
-	
-									setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
-									findMemberTypes(
-										this.completionToken,
-										(ReferenceBinding) qualifiedBinding,
-										scope,
-										scope.enclosingSourceType(),
-										false,
-										new ObjectVector());
+									if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+										setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+										findMemberTypes(
+											this.completionToken,
+											(ReferenceBinding) qualifiedBinding,
+											scope,
+											scope.enclosingSourceType(),
+											false,
+											new ObjectVector());
+									}
 	
 								} else {
 	
@@ -744,7 +672,9 @@
 					
 									this.completionToken = access.token;
 									
-									findKeywords(this.completionToken, new char[][]{Keywords.NEW});
+									if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+										findKeywords(this.completionToken, new char[][]{Keywords.NEW});
+									}
 									
 									findFieldsAndMethods(
 										this.completionToken,
@@ -765,42 +695,45 @@
 											computeTypes(messageSend.arguments, (BlockScope) scope);
 										this.completionToken = messageSend.selector;
 										if (qualifiedBinding == null) {
-											
-											findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope);
+											if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+												findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope);
+											}
 										} else {
-	
-											findMethods(
-												this.completionToken,
-												argTypes,
-												(ReferenceBinding) qualifiedBinding,
-												scope,
-												new ObjectVector(),
-												false,
-												true,
-												false,
-												messageSend,
-												scope,
-												false,
-												messageSend.receiver instanceof SuperReference,
-												true);
+											if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+												findMethods(
+													this.completionToken,
+													argTypes,
+													(ReferenceBinding) qualifiedBinding,
+													scope,
+													new ObjectVector(),
+													false,
+													true,
+													false,
+													messageSend,
+													scope,
+													false,
+													messageSend.receiver instanceof SuperReference,
+													true);
+											}
 										}
 	
 									} else {
 	
 										if (astNode instanceof CompletionOnExplicitConstructorCall) {
-											setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
-											
-											CompletionOnExplicitConstructorCall constructorCall =
-												(CompletionOnExplicitConstructorCall) astNode;
-											TypeBinding[] argTypes =
-												computeTypes(constructorCall.arguments, (BlockScope) scope);
-											findConstructors(
-												(ReferenceBinding) qualifiedBinding,
-												argTypes,
-												scope,
-												constructorCall,
-												false);
-	
+											if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+												setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
+												
+												CompletionOnExplicitConstructorCall constructorCall =
+													(CompletionOnExplicitConstructorCall) astNode;
+												TypeBinding[] argTypes =
+													computeTypes(constructorCall.arguments, (BlockScope) scope);
+												findConstructors(
+													(ReferenceBinding) qualifiedBinding,
+													argTypes,
+													scope,
+													constructorCall,
+													false);
+											}
 										} else {
 	
 											if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
@@ -812,17 +745,19 @@
 													computeTypes(allocExpression.arguments, (BlockScope) scope);
 												
 												ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
-												if(ref.isClass()) {
-													if(!ref.isAbstract()) {
+												if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+														&& ref.isClass()
+														&& !ref.isAbstract()) {
 														findConstructors(
 															ref,
 															argTypes,
 															scope,
 															allocExpression,
 															false);
-													}
 												}
-												if(!ref.isFinal()){
+												if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
+														&& !ref.isFinal()
+														&& !ref.isEnum()){
 													findAnonymousType(
 														ref,
 														argTypes,
@@ -833,86 +768,98 @@
 											} else {
 	
 												if (astNode instanceof CompletionOnClassLiteralAccess) {
-													CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
-													setSourceRange(access.classStart, access.sourceEnd);
-									
-													this.completionToken = access.completionIdentifier;
-									
-													findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
+													if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+														CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
+														setSourceRange(access.classStart, access.sourceEnd);
+										
+														this.completionToken = access.completionIdentifier;
+										
+														findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope);
+													}
 												} else {
 													if(astNode instanceof CompletionOnMethodName) {
-														CompletionOnMethodName method = (CompletionOnMethodName) astNode;
-															
-														setSourceRange(method.sourceStart, method.selectorEnd);
-															
-														FieldBinding[] fields = scope.enclosingSourceType().fields();
-														char[][] excludeNames = new char[fields.length][];
-														for(int i = 0 ; i < fields.length ; i++){
-															excludeNames[i] = fields[i].name;
-														}
-														
-														this.completionToken = method.selector;
-														
-														findVariableNames(this.completionToken, method.returnType, excludeNames, FIELD, method.modifiers);
-													} else {
-														if (astNode instanceof CompletionOnFieldName) {
-															CompletionOnFieldName field = (CompletionOnFieldName) astNode;
-															
+														if(!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+															CompletionOnMethodName method = (CompletionOnMethodName) astNode;
+																
+															setSourceRange(method.sourceStart, method.selectorEnd);
+																
 															FieldBinding[] fields = scope.enclosingSourceType().fields();
 															char[][] excludeNames = new char[fields.length][];
 															for(int i = 0 ; i < fields.length ; i++){
 																excludeNames[i] = fields[i].name;
 															}
 															
-															this.completionToken = field.realName;
+															this.completionToken = method.selector;
 															
-															findVariableNames(field.realName, field.type, excludeNames, FIELD, field.modifiers);
+															findVariableNames(this.completionToken, method.returnType, excludeNames, FIELD, method.modifiers);
+														}
+													} else {
+														if (astNode instanceof CompletionOnFieldName) {
+															if(!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+																CompletionOnFieldName field = (CompletionOnFieldName) astNode;
+																
+																FieldBinding[] fields = scope.enclosingSourceType().fields();
+																char[][] excludeNames = new char[fields.length][];
+																for(int i = 0 ; i < fields.length ; i++){
+																	excludeNames[i] = fields[i].name;
+																}
+																
+																this.completionToken = field.realName;
+																
+																findVariableNames(field.realName, field.type, excludeNames, FIELD, field.modifiers);
+															}
 														} else {
 															if (astNode instanceof CompletionOnLocalName ||
 																astNode instanceof CompletionOnArgumentName){
-																LocalDeclaration variable = (LocalDeclaration) astNode;
-																
-																LocalVariableBinding[] locals = ((BlockScope)scope).locals;
-																char[][] excludeNames = new char[locals.length][];
-																int localCount = 0;
-																for(int i = 0 ; i < locals.length ; i++){
-																	if(locals[i] != null) {
-																		excludeNames[localCount++] = locals[i].name;
+																if(!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+																	LocalDeclaration variable = (LocalDeclaration) astNode;
+																	
+																	LocalVariableBinding[] locals = ((BlockScope)scope).locals;
+																	char[][] excludeNames = new char[locals.length][];
+																	int localCount = 0;
+																	for(int i = 0 ; i < locals.length ; i++){
+																		if(locals[i] != null) {
+																			excludeNames[localCount++] = locals[i].name;
+																		}
 																	}
-																}
-																System.arraycopy(excludeNames, 0, excludeNames = new char[localCount][], 0, localCount);
-																
-																if(variable instanceof CompletionOnLocalName){
-																	this.completionToken = ((CompletionOnLocalName) variable).realName;
-																	findVariableNames(this.completionToken, variable.type, excludeNames, LOCAL, variable.modifiers);
-																} else {
-																	CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
-																	this.completionToken = arg.realName;
-																	findVariableNames(this.completionToken, variable.type, excludeNames, arg.isCatchArgument ? LOCAL : ARGUMENT, variable.modifiers);
+																	System.arraycopy(excludeNames, 0, excludeNames = new char[localCount][], 0, localCount);
+																	
+																	if(variable instanceof CompletionOnLocalName){
+																		this.completionToken = ((CompletionOnLocalName) variable).realName;
+																		findVariableNames(this.completionToken, variable.type, excludeNames, LOCAL, variable.modifiers);
+																	} else {
+																		CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
+																		this.completionToken = arg.realName;
+																		findVariableNames(this.completionToken, variable.type, excludeNames, arg.isCatchArgument ? LOCAL : ARGUMENT, variable.modifiers);
+																	}
 																}
 															} else {
 																if(astNode instanceof CompletionOnKeyword) {
-																	CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
-																	findKeywords(keyword.getToken(), keyword.getPossibleKeywords());
+																	if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+																		CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
+																		findKeywords(keyword.getToken(), keyword.getPossibleKeywords());
+																	}
 																} else if(astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
-																	CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
-																	
-																	this.insideQualifiedReference = true;
-							
-																	this.assistNodeIsClass = ref.isClass();
-																	this.assistNodeIsException = ref.isException();
-																	this.assistNodeIsInterface = ref.isInterface();
-																	
-																	this.completionToken = ref.completionIdentifier;
-																	long completionPosition = ref.sourcePositions[ref.tokens.length];
-																	setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
-																	findMemberTypes(
-																		this.completionToken,
-																		(ReferenceBinding) qualifiedBinding,
-																		scope,
-																		scope.enclosingSourceType(),
-																		false,
-																		new ObjectVector());
+																	if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+																		CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
+																		
+																		this.insideQualifiedReference = true;
+								
+																		this.assistNodeIsClass = ref.isClass();
+																		this.assistNodeIsException = ref.isException();
+																		this.assistNodeIsInterface = ref.isInterface();
+																		
+																		this.completionToken = ref.completionIdentifier;
+																		long completionPosition = ref.sourcePositions[ref.tokens.length];
+																		setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+																		findMemberTypes(
+																			this.completionToken,
+																			(ReferenceBinding) qualifiedBinding,
+																			scope,
+																			scope.enclosingSourceType(),
+																			false,
+																			new ObjectVector());
+																	}
 																} else if(astNode instanceof CompletionOnMarkerAnnotationName) {
 																	CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
 																	
@@ -926,9 +873,50 @@
 																	} else if(annot.type instanceof CompletionOnQualifiedTypeReference) {
 																		CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
 																		this.completionToken = type.completionIdentifier;
-																		setSourceRange(type.sourceStart, type.sourceEnd);
+																		long completionPosition = type.sourcePositions[type.tokens.length];
+																		setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+										
+																		findMemberTypes(
+																			this.completionToken,
+																			(ReferenceBinding) qualifiedBinding,
+																			scope,
+																			scope.enclosingSourceType(),
+																			false,
+																			new ObjectVector());
+																	}
+																} else if (astNode instanceof CompletionOnMemberValueName) {
+																	if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+																		CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
+																		Annotation annotation = (Annotation) astNodeParent;
 																		
-																		findTypesAndPackages(this.completionToken, scope);
+																		this.completionToken = memberValuePair.name;
+																		
+																		MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+																		this.findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), (ReferenceBinding)annotation.resolvedType);
+																		if(memberValuePairs == null || memberValuePairs.length == 0) {
+																			if(annotation.resolvedType instanceof ReferenceBinding) {
+																				MethodBinding[] methodBindings =
+																					((ReferenceBinding)annotation.resolvedType).availableMethods();
+																				if(methodBindings != null &&
+																						methodBindings.length == 1 &&
+																						CharOperation.equals(methodBindings[0].selector, VALUE)) {
+																					if(this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+																						findTypesAndPackages(this.completionToken, scope);
+																					} else {
+																						findVariablesAndMethods(
+																							this.completionToken,
+																							scope,
+																							FakeInvocationSite,
+																							scope,
+																							insideTypeAnnotation,
+																							true);
+																						// can be the start of a qualified type name
+																						findTypesAndPackages(this.completionToken, scope);
+																					}
+																				}
+																			}
+																			
+																		}
 																	}
 																}
 															}
@@ -951,7 +939,7 @@
 		if(this.requestor != null){
 			this.requestor.beginReporting();
 		}
-		
+		boolean contextAccepted = false;
 		IType topLevelType = type;
 		while(topLevelType.getDeclaringType() != null) {
 			topLevelType = topLevelType.getDeclaringType();
@@ -1015,12 +1003,17 @@
 					} catch (CompletionNodeFound e) {
 						//					completionNodeFound = true;
 						if (e.astNode != null) {
+							contextAccepted = true;
 							// if null then we found a problem in the completion node
-							complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope);
+							complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
 						}
 					}
 				}
 				if(this.noProposal && this.problem != null) {
+					if(!contextAccepted) {
+						contextAccepted = true;
+						this.requestor.acceptContext(new CompletionContext());
+					}
 					this.requestor.completionFailure(this.problem);
 					if(DEBUG) {
 						this.printDebug(this.problem);
@@ -1030,7 +1023,10 @@
 		} catch(JavaModelException e) {
 			// Do nothing
 		}
-		
+		if(!contextAccepted) {
+			contextAccepted = true;
+			this.requestor.acceptContext(new CompletionContext());
+		}
 		if(this.requestor != null){
 			this.requestor.endReporting();
 		}
@@ -1096,10 +1092,8 @@
 			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
 			System.out.println(sourceUnit.getContents());
 		}
-		if(this.requestor != null){
-			this.requestor.beginReporting();
-		}
-		
+		this.requestor.beginReporting();
+		boolean contextAccepted = false;
 		try {
 			this.actualCompletionPosition = completionPosition - 1;
 			this.offset = pos;
@@ -1116,7 +1110,11 @@
 
 				// scan the package & import statements first
 				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
-					findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
+					contextAccepted = true;
+					this.requestor.acceptContext(new CompletionContext());
+					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+						findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
+					}
 					if(this.noProposal && this.problem != null) {
 						this.requestor.completionFailure(this.problem);
 						if(DEBUG) {
@@ -1131,6 +1129,8 @@
 					for (int i = 0, length = imports.length; i < length; i++) {
 						ImportReference importReference = imports[i];
 						if (importReference instanceof CompletionOnImportReference) {
+							contextAccepted = true;
+							this.requestor.acceptContext(new CompletionContext());
 							findImports((CompletionOnImportReference) importReference);
 							if(this.noProposal && this.problem != null) {
 								this.requestor.completionFailure(this.problem);
@@ -1149,17 +1149,27 @@
 									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
 									if(binding != null && binding instanceof ReferenceBinding) {
 										ReferenceBinding ref = (ReferenceBinding) binding;
-										this.findImportsOfMemberTypes(lastToken, ref);
-										this.findImportsOfStaticFields(lastToken, ref);
-										this.findImportsOfStaticMethdods(lastToken, ref);
+										if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+											this.findImportsOfMemberTypes(lastToken, ref);
+										}
+										if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+											this.findImportsOfStaticFields(lastToken, ref);
+										}
+										if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+											this.findImportsOfStaticMethdods(lastToken, ref);
+										}
 									}
 								}
 							}
 							return;
 						} else if(importReference instanceof CompletionOnKeyword) {
-							setSourceRange(importReference.sourceStart, importReference.sourceEnd);
-							CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
-							findKeywords(keyword.getToken(), keyword.getPossibleKeywords());
+							contextAccepted = true;
+							this.requestor.acceptContext(new CompletionContext());
+							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+								setSourceRange(importReference.sourceStart, importReference.sourceEnd);
+								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
+								findKeywords(keyword.getToken(), keyword.getPossibleKeywords());
+							}
 							if(this.noProposal && this.problem != null) {
 								this.requestor.completionFailure(this.problem);
 								if(DEBUG) {
@@ -1197,13 +1207,19 @@
 									System.out.println(this.parser.assistNodeParent);
 								}
 							}
+							contextAccepted = true;
 							// if null then we found a problem in the completion node
-							complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope);
+							complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation);
 						}
 					}
 				}
 			}
+			
 			if(this.noProposal && this.problem != null) {
+				if(!contextAccepted) {
+					contextAccepted = true;
+					this.requestor.acceptContext(new CompletionContext());
+				}
 				this.requestor.completionFailure(this.problem);
 				if(DEBUG) {
 					this.printDebug(this.problem);
@@ -1242,9 +1258,10 @@
 			}
 		} finally {
 			reset();
-		}
-		
-		if(this.requestor != null){
+			if(!contextAccepted) {
+				contextAccepted = true;
+				this.requestor.acceptContext(new CompletionContext());
+			}
 			this.requestor.endReporting();
 		}
 	}
@@ -1261,6 +1278,41 @@
 		return argTypes;
 	}
 	
+	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
+		MethodBinding[] methods = annotation.availableMethods();
+		nextAttribute: for (int i = 0; i < methods.length; i++) {
+			MethodBinding method = methods[i];
+			
+			if(!CharOperation.prefixEquals(token, method.selector, false)) continue nextAttribute;
+			
+			int length = attributesFound == null ? 0 : attributesFound.length;
+			for (int j = 0; j < length; j++) {
+				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
+			}
+			
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForInterestingProposal(method);
+			relevance += computeRelevanceForCaseMatching(token, method.selector);
+			relevance += computeRelevanceForQualification(false);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+			
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+				CompletionProposal proposal = this.createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setSignature(getSignature(method.returnType));
+				proposal.setName(method.selector);
+				proposal.setCompletion(method.selector);
+				proposal.setFlags(method.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+		}
+	}
 	private void findAnonymousType(
 		ReferenceBinding currentType,
 		TypeBinding[] argTypes,
@@ -1268,10 +1320,6 @@
 		InvocationSite invocationSite) {
 
 		if (currentType.isInterface()) {
-			boolean hasRestrictedAccess = false;
-//			boolean hasRestrictedAccess = currentType.hasRestrictedAccess();
-//			if(this.options.checkRestrictions && hasRestrictedAccess) return;
-			
 			char[] completion = CharOperation.NO_CHAR;
 			// nothing to insert - do not want to replace the existing selector & arguments
 			if (this.source == null
@@ -1280,18 +1328,20 @@
 				completion = new char[] { ')' };
 			int relevance = computeBaseRelevance();
 			relevance += computeRelevanceForInterestingProposal();
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 			
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
 				CompletionProposal proposal = this.createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
 				proposal.setDeclarationSignature(getSignature(currentType));
+				proposal.setDeclarationKey(currentType.computeUniqueKey());
 				proposal.setSignature(
 						createMethodSignature(
 								CharOperation.NO_CHAR_CHAR,
 								CharOperation.NO_CHAR_CHAR,
 								CharOperation.NO_CHAR,
 								CharOperation.NO_CHAR));
+				//proposal.setUniqueKey(null);
 				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
 				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
 				//proposal.setParameterPackageNames(null);
@@ -1329,7 +1379,7 @@
 			relevance += computeRelevanceForInterestingProposal();
 			relevance += computeRelevanceForCaseMatching(token, classField);
 			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
-			relevance += computeRelevanceForRestrictions(false); //no access restriction for class field 
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field 
 			
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
@@ -1355,7 +1405,57 @@
 			}
 		}
 	}
+	private void findEnumConstant(char[] enumConstantName, SwitchStatement switchStatement) {
+		TypeBinding expressionType = switchStatement.expression.resolvedType;
+		if(expressionType != null && expressionType.isEnum()) {
+			ReferenceBinding enumType = (ReferenceBinding) expressionType;
+			
+			FieldBinding[] fields = enumType.fields();
+			
+			int enumConstantLength = enumConstantName.length;
+			next : for (int f = fields.length; --f >= 0;) {			
+				FieldBinding field = fields[f];
 
+				if (field.isSynthetic()) continue next;
+
+				if ((field.modifiers & Flags.AccEnum) == 0) continue next;
+
+				if (enumConstantLength > field.name.length) continue next;
+
+				if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */))	continue next;
+				
+				char[] completion = field.name;
+
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForInterestingProposal(field);
+				relevance += R_ENUM_CONSTANT;
+				relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
+				relevance += computeRelevanceForExpectingType(field.type);
+				relevance += computeRelevanceForQualification(false);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+				
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+					CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(getSignature(field.declaringClass));
+					proposal.setSignature(getSignature(field.type));
+					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+					proposal.setPackageName(field.type.qualifiedPackageName());
+					proposal.setTypeName(field.type.qualifiedSourceName()); 
+					proposal.setName(field.name);
+					proposal.setCompletion(completion);
+					proposal.setFlags(field.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+	}
 	private void findExplicitConstructors(
 		char[] name,
 		ReferenceBinding currentType,
@@ -1376,10 +1476,6 @@
 						
 					if (this.options.checkVisibility
 						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
-	
-					boolean hasRestrictedAccess = false;
-//					boolean hasRestrictedAccess = constructor.declaringClass.hasRestrictedAccess();
-//					if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
 					
 					TypeBinding[] parameters = constructor.parameters;
 					int paramLength = parameters.length;
@@ -1404,7 +1500,7 @@
 					int relevance = computeBaseRelevance();
 					relevance += computeRelevanceForInterestingProposal();
 					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
-					relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 					
 					this.noProposal = false;
 					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
@@ -1455,10 +1551,6 @@
 							continue next;
 					}
 					
-					boolean hasRestrictedAccess = false;
-//					boolean hasRestrictedAccess = constructor.declaringClass.hasRestrictedAccess();
-//					if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
-					
 					TypeBinding[] parameters = constructor.parameters;
 					int paramLength = parameters.length;
 					if (minArgLength > paramLength)
@@ -1487,13 +1579,15 @@
 					if(forAnonymousType){
 						int relevance = computeBaseRelevance();
 						relevance += computeRelevanceForInterestingProposal();
-						relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 						
 						this.noProposal = false;
 						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
 							CompletionProposal proposal = this.createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
 							proposal.setDeclarationSignature(getSignature(currentType));
+							proposal.setDeclarationKey(currentType.computeUniqueKey());
 							proposal.setSignature(getSignature(constructor));
+							proposal.setKey(constructor.computeUniqueKey());
 							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
 							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
 							proposal.setParameterPackageNames(parameterPackageNames);
@@ -1513,7 +1607,7 @@
 					} else {
 						int relevance = computeBaseRelevance();
 						relevance += computeRelevanceForInterestingProposal();
-						relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 						
 						this.noProposal = false;
 						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
@@ -1575,10 +1669,6 @@
 
 			if (this.options.checkVisibility
 				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
-			
-			boolean hasRestrictedAccess = false;
-//			boolean hasRestrictedAccess = field.declaringClass.hasRestrictedAccess();
-//			if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
 
 			boolean prefixRequired = false;
 
@@ -1640,7 +1730,7 @@
 			relevance += computeRelevanceForExpectingType(field.type);
 			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
 			relevance += computeRelevanceForQualification(prefixRequired);
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 			
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
@@ -1785,10 +1875,14 @@
 		if (receiverType.isBaseType())
 			return; // nothing else is possible with base types
 		
+		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
+		
 		ObjectVector methodsFound = new ObjectVector();
 		
 		if (receiverType.isArrayType()) {
-			if (token.length <= lengthField.length
+			if (proposeField
+				&& token.length <= lengthField.length
 				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
 			)) {
 				
@@ -1796,7 +1890,7 @@
 				relevance += computeRelevanceForInterestingProposal();
 				relevance += computeRelevanceForCaseMatching(token,lengthField);
 				relevance += computeRelevanceForExpectingType(BaseTypes.IntBinding);
-				relevance += computeRelevanceForRestrictions(false); // no access restriction for length field
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
 				
 				this.noProposal = false;
 				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
@@ -1818,7 +1912,8 @@
 					}
 				}
 			}
-			if (token.length <= cloneMethod.length
+			if (proposeMethod
+				&& token.length <= cloneMethod.length
 				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */
 			)) {
 				ReferenceBinding objectRef = scope.getJavaLangObject();
@@ -1829,7 +1924,7 @@
 				relevance += computeRelevanceForExpectingType(objectRef);
 				relevance += computeRelevanceForStatic(false, false);
 				relevance += computeRelevanceForQualification(false);
-				relevance += computeRelevanceForRestrictions(false); // no access restriction for clone() method
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
 				
 				char[] completion;
 				if (this.source != null
@@ -1871,32 +1966,36 @@
 			receiverType = scope.getJavaLangObject();
 		}
 
-		findFields(
-			token,
-			(ReferenceBinding) receiverType,
-			scope,
-			new ObjectVector(),
-			new ObjectVector(),
-			false,
-			invocationSite,
-			invocationScope,
-			implicitCall,
-			true);
+		if(proposeField) {
+			findFields(
+				token,
+				(ReferenceBinding) receiverType,
+				scope,
+				new ObjectVector(),
+				new ObjectVector(),
+				false,
+				invocationSite,
+				invocationScope,
+				implicitCall,
+				true);
+		}
 
-		findMethods(
-			token,
-			null,
-			(ReferenceBinding) receiverType,
-			scope,
-			methodsFound,
-			false,
-			false,
-			false,
-			invocationSite,
-			invocationScope,
-			implicitCall,
-			superCall,
-			true);
+		if(proposeMethod) {
+			findMethods(
+				token,
+				null,
+				(ReferenceBinding) receiverType,
+				scope,
+				methodsFound,
+				false,
+				false,
+				false,
+				invocationSite,
+				invocationScope,
+				implicitCall,
+				superCall,
+				true);
+		}
 	}
 
 	private void findImports(CompletionOnImportReference importReference) {
@@ -1918,8 +2017,12 @@
 			
 		this.completionToken =  importName;
 		// want to replace the existing .*;
-		this.nameEnvironment.findPackages(importName, this);
-		this.nameEnvironment.findTypes(importName, this);
+		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+			this.nameEnvironment.findPackages(importName, this);
+		}
+		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+			this.nameEnvironment.findTypes(importName, this);
+		}
 	}
 	
 	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref) {
@@ -1943,9 +2046,6 @@
 				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
 				continue next;
 			
-			boolean hasRestrictedAccess = false;
-//				boolean hasRestrictedAccess = memberType.hasRestrictedAccess();
-//				if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
 			char[] completionName = CharOperation.concat(
 					memberType.qualifiedPackageName(),
 					memberType.qualifiedSourceName(),
@@ -1956,46 +2056,29 @@
 			int relevance = computeBaseRelevance();
 			relevance += computeRelevanceForInterestingProposal();
 			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 
 			if (memberType.isClass()) {
 				relevance += computeRelevanceForClass();
-				
-				this.noProposal = false;
-				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-					CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-					proposal.setDeclarationSignature(memberType.qualifiedPackageName());
-					proposal.setSignature(getSignature(memberType));
-					proposal.setPackageName(memberType.qualifiedPackageName());
-					proposal.setTypeName(memberType.qualifiedSourceName());
-					proposal.setCompletion(completionName);
-					proposal.setFlags(memberType.modifiers);
-					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-					proposal.setRelevance(relevance);
-					this.requestor.accept(proposal);
-					if(DEBUG) {
-						this.printDebug(proposal);
-					}
-				}
-
-			} else {
+			} else if(memberType.isEnum()) {
+				relevance += computeRelevanceForEnum();
+			} else if (memberType.isInterface()) {
 				relevance += computeRelevanceForInterface();
-				
-				this.noProposal = false;
-				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-					CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-					proposal.setDeclarationSignature(memberType.qualifiedPackageName());
-					proposal.setSignature(getSignature(memberType));
-					proposal.setPackageName(memberType.qualifiedPackageName());
-					proposal.setTypeName(memberType.qualifiedSourceName());
-					proposal.setCompletion(completionName);
-					proposal.setFlags(memberType.modifiers | Flags.AccInterface);
-					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-					proposal.setRelevance(relevance);
-					this.requestor.accept(proposal);
-					if(DEBUG) {
-						this.printDebug(proposal);
-					}
+			}
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+				CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(memberType.qualifiedPackageName());
+				proposal.setSignature(getSignature(memberType));
+				proposal.setPackageName(memberType.qualifiedPackageName());
+				proposal.setTypeName(memberType.qualifiedSourceName());
+				proposal.setCompletion(completionName);
+				proposal.setFlags(memberType.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
 				}
 			}
 		}
@@ -2026,9 +2109,6 @@
 				&& !field.canBeSeenBy(this.unitScope.fPackage))
 				continue next;
 			
-			boolean hasRestrictedAccess = false;
-//				boolean hasRestrictedAccess = field.declaringClass.hasRestrictedAccess();
-//				if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
 			char[] completionName = CharOperation.concat(
 					field.declaringClass.qualifiedPackageName(),
 					'.',
@@ -2041,7 +2121,7 @@
 			int relevance = computeBaseRelevance();
 			relevance += computeRelevanceForInterestingProposal();
 			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
@@ -2091,10 +2171,6 @@
 				))
 				continue next;
 			
-			boolean hasRestrictedAccess = false;
-//				boolean hasRestrictedAccess = method.declaringClass.hasRestrictedAccess();
-//				if (this.options.checkRestrictions && hasRestrictedAccess) continue next;
-			
 			int length = method.parameters.length;
 			char[][] parameterPackageNames = new char[length][];
 			char[][] parameterTypeNames = new char[length][];
@@ -2119,7 +2195,7 @@
 			int relevance = computeBaseRelevance();
 			relevance += computeRelevanceForInterestingProposal();
 			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
@@ -2160,8 +2236,12 @@
 					int relevance = computeBaseRelevance();
 					relevance += computeRelevanceForInterestingProposal();
 					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
-					relevance += computeRelevanceForRestrictions(false); // no access restriction for keywors
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
 					
+					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
+						relevance += computeRelevanceForExpectingType(BaseTypes.BooleanBinding);
+						relevance += computeRelevanceForQualification(false);
+					}
 					this.noProposal = false;
 					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
 						CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
@@ -2176,6 +2256,38 @@
 					}
 				}
 	}
+	private void findTrueOrFalseKeywords(char[][] choices) {
+		if(choices == null || choices.length == 0) return;
+		
+		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != BaseTypes.BooleanBinding) return;
+		
+		for (int i = 0; i < choices.length; i++) {
+			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
+					CharOperation.equals(choices[i], Keywords.FALSE)
+			){
+				int relevance = computeBaseRelevance();
+				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
+				relevance += computeRelevanceForExpectingType(BaseTypes.BooleanBinding);
+				relevance += computeRelevanceForQualification(false);
+				relevance += R_TRUE_OR_FALSE;
+
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+					CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+					proposal.setName(choices[i]);
+					proposal.setCompletion(choices[i]);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
+					}
+				}
+			}
+		}
+	}
 	
 	private void findKeywordsForMember(char[] token, int modifiers) {
 		char[][] keywords = new char[Keywords.COUNT][];
@@ -2286,6 +2398,8 @@
 			
 			if (staticOnly && !memberType.isStatic()) continue next;
 			
+			if (isForbidden(memberType)) continue next;
+			
 			if (typeLength > memberType.sourceName.length)
 				continue next;
 
@@ -2294,13 +2408,13 @@
 				))
 				continue next;
 
-			if (this.options.checkVisibility
-				&& !memberType.canBeSeenBy(receiverType, invocationType))
-				continue next;
-			
-			boolean hasRestrictedAccess = false;
-//			boolean hasRestrictedAccess = memberType.hasRestrictedAccess();
-//			if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
+			if (this.options.checkVisibility) {
+				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
+					continue next;
+				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
+					continue next;
+				}
+			}
 
 			for (int i = typesFound.size; --i >= 0;) {
 				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
@@ -2331,47 +2445,31 @@
 			relevance += computeRelevanceForInterestingProposal();
 			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
 			relevance += computeRelevanceForExpectingType(memberType);
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 
 			if (memberType.isClass()) {
 				relevance += computeRelevanceForClass();
 				relevance += computeRelevanceForException(memberType.sourceName);
-				
-				this.noProposal = false;
-				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-					CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-					proposal.setDeclarationSignature(memberType.qualifiedPackageName());
-					proposal.setSignature(getSignature(memberType));
-					proposal.setPackageName(memberType.qualifiedPackageName());
-					proposal.setTypeName(memberType.qualifiedSourceName());
-					proposal.setCompletion(memberType.sourceName());
-					proposal.setFlags(memberType.modifiers);
-					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-					proposal.setRelevance(relevance);
-					this.requestor.accept(proposal);
-					if(DEBUG) {
-						this.printDebug(proposal);
-					}
-				}
-
-			} else {
+			} else if(memberType.isEnum()) {
+				relevance += computeRelevanceForEnum();
+			} else if(memberType.isInterface()) {
 				relevance += computeRelevanceForInterface();
+			}
 				
-				this.noProposal = false;
-				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-					CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-					proposal.setDeclarationSignature(memberType.qualifiedPackageName());
-					proposal.setSignature(getSignature(memberType));
-					proposal.setPackageName(memberType.qualifiedPackageName());
-					proposal.setTypeName(memberType.qualifiedSourceName());
-					proposal.setCompletion(memberType.sourceName());
-					proposal.setFlags(memberType.modifiers | Flags.AccInterface);
-					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-					proposal.setRelevance(relevance);
-					this.requestor.accept(proposal);
-					if(DEBUG) {
-						this.printDebug(proposal);
-					}
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+				CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(memberType.qualifiedPackageName());
+				proposal.setSignature(getSignature(memberType));
+				proposal.setPackageName(memberType.qualifiedPackageName());
+				proposal.setTypeName(memberType.qualifiedSourceName());
+				proposal.setCompletion(memberType.sourceName());
+				proposal.setFlags(memberType.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setRelevance(relevance);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
 				}
 			}
 		}
@@ -2663,10 +2761,6 @@
 
 			if (this.options.checkVisibility
 				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
-			
-			boolean hasRestrictedAccess = false;
-//			boolean hasRestrictedAccess = method.declaringClass.hasRestrictedAccess();
-//			if (this.options.checkRestrictions && hasRestrictedAccess) continue next;
 
 			if(superCall && method.isAbstract()) {
 				methodsFound.add(new Object[]{method, receiverType});
@@ -2788,7 +2882,7 @@
 			relevance += computeRelevanceForExpectingType(method.returnType);
 			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
 			relevance += computeRelevanceForQualification(prefixRequired);
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 			
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
@@ -2818,6 +2912,89 @@
 		methodsFound.addAll(newMethodsFound);
 	}
 	
+	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
+	private void findLocalMethodsOfStaticImports(
+		char[] methodName,
+		MethodBinding[] methods,
+		Scope scope,
+		ReferenceBinding receiverType,
+		InvocationSite invocationSite) {
+
+		next : for (int f = methods.length; --f >= 0;) {
+			MethodBinding method = methods[f];
+
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (!method.isStatic()) continue next;
+
+			if (this.options.checkVisibility
+				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */))
+				continue next;
+
+			int length = method.parameters.length;
+			char[][] parameterPackageNames = new char[length][];
+			char[][] parameterTypeNames = new char[length][];
+
+			for (int i = 0; i < length; i++) {
+				TypeBinding type = method.original().parameters[i];
+				parameterPackageNames[i] = type.qualifiedPackageName();
+				parameterTypeNames[i] = type.qualifiedSourceName();
+			}
+			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+
+			char[] completion = CharOperation.NO_CHAR;
+			
+			int previousStartPosition = this.startPosition;
+			
+			// nothing to insert - do not want to replace the existing selector & arguments
+			if (this.source != null
+				&& this.source.length > this.endPosition
+				&& this.source[this.endPosition] == '(') {
+				completion = method.selector;
+			} else {
+				completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
+			}
+			
+			int relevance = computeBaseRelevance();
+			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+			relevance += computeRelevanceForExpectingType(method.returnType);
+			relevance += computeRelevanceForStatic(true, method.isStatic());
+			relevance += computeRelevanceForQualification(false);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+			
+			this.noProposal = false;
+			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+				CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setSignature(getSignature(method));
+				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+				proposal.setParameterPackageNames(parameterPackageNames);
+				proposal.setParameterTypeNames(parameterTypeNames);
+				proposal.setPackageName(method.returnType.qualifiedPackageName());
+				proposal.setTypeName(method.returnType.qualifiedSourceName());
+				proposal.setName(method.selector);
+				proposal.setCompletion(completion);
+				proposal.setFlags(method.modifiers);
+				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+				proposal.setRelevance(relevance);
+				if(parameterNames != null) proposal.setParameterNames(parameterNames);
+				this.requestor.accept(proposal);
+				if(DEBUG) {
+					this.printDebug(proposal);
+				}
+			}
+			this.startPosition = previousStartPosition;
+		}
+	}
+	
 	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
 		if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
 			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
@@ -2844,6 +3021,12 @@
 		}
 		return 0;
 	}
+	private int computeRelevanceForEnum(){
+		if(this.assistNodeIsEnum) {
+			return R_ENUM;
+		}
+		return 0;
+	}
 	private int computeRelevanceForInterface(){
 		if(this.assistNodeIsInterface) {
 			return R_INTERFACE;
@@ -2860,8 +3043,8 @@
 		}
 		return 0;
 	}
-	int computeRelevanceForRestrictions(boolean hasRestrictedAccess) {
-		if(!hasRestrictedAccess) {
+	int computeRelevanceForRestrictions(int accessRuleKind) {
+		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
 			return R_NON_RESTRICTED;
 		}
 		return 0;
@@ -2974,10 +3157,6 @@
 			if (this.options.checkVisibility
 				&& !method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
 
-			boolean hasRestrictedAccess = false;
-//			boolean hasRestrictedAccess = method.declaringClass.hasRestrictedAccess();
-//			if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
-			
 			if (exactMatch) {
 				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
 					))
@@ -3086,13 +3265,15 @@
 			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
 			relevance += computeRelevanceForStaticOveride(method.isStatic());
 			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
-			relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 			
 			this.noProposal = false;
 			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
 				CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
 				proposal.setDeclarationSignature(getSignature(method.declaringClass));
+				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
 				proposal.setSignature(getSignature(method));
+				proposal.setKey(method.computeUniqueKey());
 				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
 				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
 				proposal.setParameterPackageNames(parameterPackageNames);
@@ -3303,17 +3484,21 @@
 			}
 			
 			if(sourceType != null) {
-				ISourceMethod[] sourceMethods = sourceType.getMethods();
+				SourceMethod[] sourceMethods = ((SourceTypeElementInfo) sourceType).getMethodHandles();
 				int len = sourceMethods.length;
 				for(int i = 0; i < len ; i++){
-					ISourceMethod sourceMethod = sourceMethods[i];
-					char[][] argTypeNames = sourceMethod.getArgumentTypeNames();
+					SourceMethod sourceMethod = sourceMethods[i];
+					String[] argTypeSignatures = sourceMethod.getParameterTypes();
 
-					if(argTypeNames != null &&
-						CharOperation.equals(method.selector,sourceMethod.getSelector()) &&
-						CharOperation.equals(argTypeNames,parameterTypeNames)){
-						parameterNames = sourceMethod.getArgumentNames();
-						break;
+					if(argTypeSignatures != null &&
+						CharOperation.equals(method.selector,sourceMethod.getElementName().toCharArray()) &&
+						equalSignatures(parameterTypeNames, argTypeSignatures)){
+						try {
+							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
+							break;
+						} catch (JavaModelException e) {
+							// method doesn't exist: ignore
+						}
 					}
 				}
 			}
@@ -3321,6 +3506,18 @@
 		return parameterNames;
 	}
 	
+	private boolean equalSignatures(char[][] typeNames, String[] typeSignatures) {
+		if (typeNames == null || typeSignatures == null)
+			return false;
+		if (typeNames.length != typeSignatures.length)
+			return false;
+
+		for (int i = typeNames.length; --i >= 0;)
+			if (!CharOperation.equals(typeNames[i], Signature.toCharArray(typeSignatures[i].toCharArray())))
+				return false;
+		return true;
+	}
+	
 	private void findNestedTypes(
 		char[] typeName,
 		SourceTypeBinding currentType,
@@ -3346,6 +3543,8 @@
 								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
 
 							if (!localType.isAnonymousType()) {
+								if (this.isForbidden(localType))
+									continue next;
 								if (typeLength > localType.sourceName.length)
 									continue next;
 								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false
@@ -3360,7 +3559,7 @@
 								relevance += computeRelevanceForException(localType.sourceName);
 								relevance += computeRelevanceForClass();
 								relevance += computeRelevanceForQualification(false);
-								relevance += computeRelevanceForRestrictions(false); // no access restriction for nested type
+								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
 								
 								this.noProposal = false;
 								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
@@ -3407,6 +3606,8 @@
 	}
 
 	private void findTypeParameters(char[] token, Scope scope) {
+		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
+		
 		TypeParameter[] typeParameters = null;
 		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
 			typeParameters = null;
@@ -3433,6 +3634,8 @@
 					int typeLength = token.length;
 					TypeParameter typeParameter = typeParameters[i];
 					
+					if(typeParameter.binding == null) continue;
+					
 					if (typeLength > typeParameter.name.length) continue;
 					
 					if (!CharOperation.prefixEquals(token, typeParameter.name, false)) continue;
@@ -3443,7 +3646,7 @@
 					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
 					relevance += computeRelevanceForQualification(false);
 					relevance += computeRelevanceForException(typeParameter.name);
-					relevance += computeRelevanceForRestrictions(false); // no access restriction fot type parameter
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
 					
 					this.noProposal = false;
 					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
@@ -3471,19 +3674,25 @@
 
 		if (token == null)
 			return;
+		
+		boolean proposeType = !this.requestor.isIgnored(CompletionProposal.TYPE_REF);
+		
 		ObjectVector typesFound = new ObjectVector();
 		
-		if (scope.enclosingSourceType() != null) {
+		if (proposeType && scope.enclosingSourceType() != null) {
 			findNestedTypes(token, scope.enclosingSourceType(), scope, typesFound);
 			findTypeParameters(token, scope);
 		}
 
-		if (this.unitScope != null) {
+		if (proposeType && this.unitScope != null) {
 			int typeLength = token.length;
 			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
 
 			for (int i = 0, length = types.length; i < length; i++) {
 				SourceTypeBinding sourceType = types[i]; 
+				
+				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
+				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
 
 				if (typeLength > sourceType.sourceName.length)	continue;
 				
@@ -3491,66 +3700,68 @@
 				
 				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
 
+				if(isForbidden(sourceType)) continue;
+					
 				int relevance = computeBaseRelevance();
 				relevance += computeRelevanceForInterestingProposal();
 				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
 				relevance += computeRelevanceForExpectingType(sourceType);
 				relevance += computeRelevanceForQualification(false);
-				relevance += computeRelevanceForRestrictions(false); // no access restriction for type in the current unit
+				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
 
-				if (sourceType.isClass()){
+				if (sourceType.isAnnotationType()) {
+					relevance += computeRelevanceForAnnotation();
+				} else if (sourceType.isInterface()) {
+					relevance += computeRelevanceForInterface();
+				} else {
 					relevance += computeRelevanceForClass();
 					relevance += computeRelevanceForException(sourceType.sourceName);
-					
-					this.noProposal = false;
-					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-						CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-						proposal.setDeclarationSignature(sourceType.qualifiedPackageName());
-						proposal.setSignature(getSignature(sourceType));
-						proposal.setPackageName(sourceType.qualifiedPackageName());
-						proposal.setTypeName(sourceType.sourceName());
-						proposal.setCompletion(sourceType.sourceName());
-						proposal.setFlags(sourceType.modifiers);
-						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-						proposal.setRelevance(relevance);
-						this.requestor.accept(proposal);
-						if(DEBUG) {
-							this.printDebug(proposal);
-						}
-					}
-				} else {
-					relevance += computeRelevanceForInterface();
-					
-					this.noProposal = false;
-					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-						CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-						proposal.setDeclarationSignature(sourceType.qualifiedPackageName());
-						proposal.setSignature(getSignature(sourceType));
-						proposal.setPackageName(sourceType.qualifiedPackageName());
-						proposal.setTypeName(sourceType.sourceName());
-						proposal.setCompletion(sourceType.sourceName());
-						proposal.setFlags(sourceType.modifiers | Flags.AccInterface);
-						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-						proposal.setRelevance(relevance);
-						this.requestor.accept(proposal);
-						if(DEBUG) {
-							this.printDebug(proposal);
-						}
+				}
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+					CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(sourceType.qualifiedPackageName());
+					proposal.setSignature(getSignature(sourceType));
+					proposal.setPackageName(sourceType.qualifiedPackageName());
+					proposal.setTypeName(sourceType.sourceName());
+					proposal.setCompletion(sourceType.sourceName());
+					proposal.setFlags(sourceType.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setRelevance(relevance);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
 					}
 				}
 			}
 		}
 		
-		this.findTypesFromStaticImports(token, scope, typesFound);
+		if(proposeType) {
+			this.findTypesFromStaticImports(token, scope, typesFound);
+		}
 		
 		if (token.length == 0) {
-			if(this.expectedTypesPtr > -1) {
+			if(proposeType && this.expectedTypesPtr > -1) {
 				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
 					if(this.expectedTypes[i] instanceof ReferenceBinding) {
 						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
 						
-						boolean hasRestrictedAccess = refBinding.hasRestrictedAccess();
-						if(this.options.checkRestrictions && hasRestrictedAccess) continue next;
+						int accessibility = IAccessRule.K_ACCESSIBLE;
+						if(refBinding.hasRestrictedAccess()) {
+							AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding);
+							if(accessRestriction != null) {
+								switch (accessRestriction.getProblemId()) {
+									case IProblem.ForbiddenReference:
+										if(this.options.checkForbiddenReference) return;
+										accessibility = IAccessRule.K_NON_ACCESSIBLE;
+										break;
+									case IProblem.DiscouragedReference:
+										if(this.options.checkDiscouragedReference) return;
+										accessibility = IAccessRule.K_DISCOURAGED;
+										break;
+								}
+							}
+						}
 						
 						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
 						
@@ -3576,45 +3787,31 @@
 							relevance += computeRelevanceForCaseMatching(token, typeName);
 							relevance += computeRelevanceForExpectingType(refBinding);
 							relevance += computeRelevanceForQualification(isQualified);
-							relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+							relevance += computeRelevanceForRestrictions(accessibility);
 							
 							if(refBinding.isClass()) {
 								relevance += computeRelevanceForClass();
-								
-								this.noProposal = false;
-								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-									CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-									proposal.setDeclarationSignature(packageName);
-									proposal.setSignature(getSignature(refBinding));
-									proposal.setPackageName(packageName);
-									proposal.setTypeName(typeName);
-									proposal.setCompletion(completionName);
-									proposal.setFlags(refBinding.modifiers);
-									proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-									proposal.setRelevance(relevance);
-									this.requestor.accept(proposal);
-									if(DEBUG) {
-										this.printDebug(proposal);
-									}
-								}
-							} else if (refBinding.isInterface()) {
+							} else if(refBinding.isEnum()) {
+								relevance += computeRelevanceForEnum();
+							} else if(refBinding.isInterface()) {
 								relevance += computeRelevanceForInterface();
+							}
 								
-								this.noProposal = false;
-								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-									CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-									proposal.setDeclarationSignature(packageName);
-									proposal.setSignature(getSignature(refBinding));
-									proposal.setPackageName(packageName);
-									proposal.setTypeName(typeName);
-									proposal.setCompletion(completionName);
-									proposal.setFlags(refBinding.modifiers | Flags.AccInterface);
-									proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-									proposal.setRelevance(relevance);
-									this.requestor.accept(proposal);
-									if(DEBUG) {
-										this.printDebug(proposal);
-									}
+							this.noProposal = false;
+							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+								CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(packageName);
+								proposal.setSignature(getSignature(refBinding));
+								proposal.setPackageName(packageName);
+								proposal.setTypeName(typeName);
+								proposal.setCompletion(completionName);
+								proposal.setFlags(refBinding.modifiers);
+								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								proposal.setRelevance(relevance);
+								proposal.setAccessibility(accessibility);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
 								}
 							}
 						}
@@ -3622,9 +3819,15 @@
 				}
 			} 
 		} else {
-			findKeywords(token, baseTypes);
-			this.nameEnvironment.findTypes(token, this);
-			this.nameEnvironment.findPackages(token, this);
+			if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+				findKeywords(token, baseTypes);
+			}
+			if(proposeType) {
+				this.nameEnvironment.findTypes(token, this);
+			}
+			if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+				this.nameEnvironment.findPackages(token, this);
+			}
 		}
 	}
 
@@ -3632,6 +3835,8 @@
 		char[] token,
 		PackageBinding packageBinding) {
 
+		boolean proposeType = !this.requestor.isIgnored(CompletionProposal.TYPE_REF);
+		
 		char[] qualifiedName =
 			CharOperation.concatWith(packageBinding.compoundName, token, '.');
 
@@ -3648,7 +3853,7 @@
 		
 		this.qualifiedCompletionToken = qualifiedName;
 		
-		if (this.unitScope != null) {
+		if (proposeType && this.unitScope != null) {
 			int typeLength = qualifiedName.length;
 			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
 
@@ -3657,12 +3862,28 @@
 	
 				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
 				
+				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
+				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
 				if (typeLength > qualifiedSourceTypeName.length) continue;
 				if (!(packageBinding == sourceType.getPackage())) continue;
 				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false))	continue;
 				
-				boolean hasRestrictedAccess = sourceType.hasRestrictedAccess();
-				if(this.options.checkRestrictions && hasRestrictedAccess) continue;
+				int accessibility = IAccessRule.K_ACCESSIBLE;
+				if(sourceType.hasRestrictedAccess()) {
+					AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(sourceType);
+					if(accessRestriction != null) {
+						switch (accessRestriction.getProblemId()) {
+							case IProblem.ForbiddenReference:
+								if(this.options.checkForbiddenReference) return;
+								accessibility = IAccessRule.K_NON_ACCESSIBLE;
+								break;
+							case IProblem.DiscouragedReference:
+								if(this.options.checkDiscouragedReference) return;
+								accessibility = IAccessRule.K_DISCOURAGED;
+								break;
+						}
+					}
+				}
 				
 				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
 
@@ -3671,53 +3892,42 @@
 				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
 				relevance += computeRelevanceForExpectingType(sourceType);
 				relevance += computeRelevanceForQualification(false);
-				relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+				relevance += computeRelevanceForRestrictions(accessibility);
 				
-				if (sourceType.isClass()){
+				if (sourceType.isAnnotationType()) {
+					relevance += computeRelevanceForAnnotation();
+				} else if (sourceType.isInterface()) {
+					relevance += computeRelevanceForInterface();
+				} else {
 					relevance += computeRelevanceForClass();
 					relevance += computeRelevanceForException(sourceType.sourceName);
-					
-					this.noProposal = false;
-					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-						CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-						proposal.setDeclarationSignature(sourceType.qualifiedPackageName());
-						proposal.setSignature(getSignature(sourceType));
-						proposal.setPackageName(sourceType.qualifiedPackageName());
-						proposal.setTypeName(sourceType.sourceName());
-						proposal.setCompletion(sourceType.sourceName());
-						proposal.setFlags(sourceType.modifiers);
-						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-						proposal.setRelevance(relevance);
-						this.requestor.accept(proposal);
-						if(DEBUG) {
-							this.printDebug(proposal);
-						}
-					}
-				} else {
-					relevance += computeRelevanceForInterface();
-					
-					this.noProposal = false;
-					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-						CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-						proposal.setDeclarationSignature(sourceType.qualifiedPackageName());
-						proposal.setSignature(getSignature(sourceType));
-						proposal.setPackageName(sourceType.qualifiedPackageName());
-						proposal.setTypeName(sourceType.sourceName());
-						proposal.setCompletion(sourceType.sourceName());
-						proposal.setFlags(sourceType.modifiers | Flags.AccInterface);
-						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-						proposal.setRelevance(relevance);
-						this.requestor.accept(proposal);
-						if(DEBUG) {
-							this.printDebug(proposal);
-						}
+				}
+				this.noProposal = false;
+				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+					CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+					proposal.setDeclarationSignature(sourceType.qualifiedPackageName());
+					proposal.setSignature(getSignature(sourceType));
+					proposal.setPackageName(sourceType.qualifiedPackageName());
+					proposal.setTypeName(sourceType.sourceName());
+					proposal.setCompletion(sourceType.sourceName());
+					proposal.setFlags(sourceType.modifiers);
+					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+					proposal.setRelevance(relevance);
+					proposal.setAccessibility(accessibility);
+					this.requestor.accept(proposal);
+					if(DEBUG) {
+						this.printDebug(proposal);
 					}
 				}
 			}
 		}
 		
-		this.nameEnvironment.findTypes(qualifiedName, this);
-		this.nameEnvironment.findPackages(qualifiedName, this);
+		if(proposeType) {
+			this.nameEnvironment.findTypes(qualifiedName, this);
+		}
+		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+			this.nameEnvironment.findPackages(qualifiedName, this);
+		}
 	}
 
 	private void findTypesFromStaticImports(char[] token, Scope scope, ObjectVector typesFound) {
@@ -3746,10 +3956,6 @@
 							
 							if (typeLength > typeBinding.sourceName.length)	continue;
 							
-							boolean hasRestrictedAccess = false;
-//							boolean hasRestrictedAccess = typeBinding.hasRestrictedAccess();
-//							if(this.options.checkRestrictions && hasRestrictedAccess) continue;
-							
 							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false))	continue;
 							
 							if (typesFound.contains(typeBinding))  continue;
@@ -3760,46 +3966,31 @@
 							relevance += computeRelevanceForInterestingProposal();
 							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
 							relevance += computeRelevanceForExpectingType(typeBinding);
-							relevance += computeRelevanceForRestrictions(hasRestrictedAccess);
+							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 							
-							if (typeBinding.isClass()){
+							if (typeBinding.isClass()) {
 								relevance += computeRelevanceForClass();
 								relevance += computeRelevanceForException(typeBinding.sourceName);
-								
-								this.noProposal = false;
-								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-									CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-									proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
-									proposal.setSignature(getSignature(typeBinding));
-									proposal.setPackageName(typeBinding.qualifiedPackageName());
-									proposal.setTypeName(typeBinding.qualifiedSourceName());
-									proposal.setCompletion(typeBinding.sourceName());
-									proposal.setFlags(typeBinding.modifiers);
-									proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-									proposal.setRelevance(relevance);
-									this.requestor.accept(proposal);
-									if(DEBUG) {
-										this.printDebug(proposal);
-									}
-								}
-							} else {
+							} else if(typeBinding.isEnum()) {
+								relevance += computeRelevanceForEnum();
+							} else if(typeBinding.isInterface()) {
 								relevance += computeRelevanceForInterface();
+							}
 								
-								this.noProposal = false;
-								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
-									CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
-									proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
-									proposal.setSignature(getSignature(typeBinding));
-									proposal.setPackageName(typeBinding.qualifiedPackageName());
-									proposal.setTypeName(typeBinding.qualifiedSourceName());
-									proposal.setCompletion(typeBinding.sourceName());
-									proposal.setFlags(typeBinding.modifiers);
-									proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-									proposal.setRelevance(relevance);
-									this.requestor.accept(proposal);
-									if(DEBUG) {
-										this.printDebug(proposal);
-									}
+							this.noProposal = false;
+							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+								CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
+								proposal.setSignature(getSignature(typeBinding));
+								proposal.setPackageName(typeBinding.qualifiedPackageName());
+								proposal.setTypeName(typeBinding.qualifiedSourceName());
+								proposal.setCompletion(typeBinding.sourceName());
+								proposal.setFlags(typeBinding.modifiers);
+								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								proposal.setRelevance(relevance);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
 								}
 							}
 						}
@@ -3812,7 +4003,9 @@
 		char[] token,
 		Scope scope,
 		InvocationSite invocationSite,
-		Scope invocationScope) {
+		Scope invocationScope,
+		boolean insideTypeAnnotation,
+		boolean insideAnnotationAttribute) {
 
 		if (token == null)
 			return;
@@ -3830,187 +4023,217 @@
 
 		Scope currentScope = scope;
 
-		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-
-			switch (currentScope.kind) {
-
-				case Scope.METHOD_SCOPE :
-					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
-					MethodScope methodScope = (MethodScope) currentScope;
-					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
-
-				case Scope.BLOCK_SCOPE :
-					BlockScope blockScope = (BlockScope) currentScope;
-
-					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
-						LocalVariableBinding local = blockScope.locals[i];
-
-						if (local == null)
-							break next;
-
-						if (tokenLength > local.name.length)
-							continue next;
-
-						if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */
-							))
-							continue next;
-
-						if (local.isSecret())
-							continue next;
-
-						for (int f = 0; f < localsFound.size; f++) {
-							LocalVariableBinding otherLocal =
-								(LocalVariableBinding) localsFound.elementAt(f);
-							if (CharOperation.equals(otherLocal.name, local.name, true))
+		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+	
+				switch (currentScope.kind) {
+	
+					case Scope.METHOD_SCOPE :
+						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+						MethodScope methodScope = (MethodScope) currentScope;
+						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+	
+					case Scope.BLOCK_SCOPE :
+						BlockScope blockScope = (BlockScope) currentScope;
+	
+						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+							LocalVariableBinding local = blockScope.locals[i];
+	
+							if (local == null)
+								break next;
+	
+							if (tokenLength > local.name.length)
 								continue next;
-						}
-						localsFound.add(local);
-
-						int relevance = computeBaseRelevance();
-						relevance += computeRelevanceForInterestingProposal(local);
-						relevance += computeRelevanceForCaseMatching(token, local.name);
-						relevance += computeRelevanceForExpectingType(local.type);
-						relevance += computeRelevanceForQualification(false);
-						relevance += computeRelevanceForRestrictions(false); // no access restriction for local variable
-						this.noProposal = false;
-						if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
-							CompletionProposal proposal = this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
-							proposal.setSignature(
-								local.type == null
-								? createTypeSignature(
-										CharOperation.NO_CHAR,
-										local.declaration.type.toString().toCharArray())
-								: getSignature(local.type));
-							if(local.type == null) {
-								//proposal.setPackageName(null);
-								proposal.setTypeName(local.declaration.type.toString().toCharArray());
-							} else {
-								proposal.setPackageName(local.type.qualifiedPackageName());
-								proposal.setTypeName(local.type.qualifiedSourceName());
+	
+							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */
+								))
+								continue next;
+	
+							if (local.isSecret())
+								continue next;
+	
+							for (int f = 0; f < localsFound.size; f++) {
+								LocalVariableBinding otherLocal =
+									(LocalVariableBinding) localsFound.elementAt(f);
+								if (CharOperation.equals(otherLocal.name, local.name, true))
+									continue next;
 							}
-							proposal.setName(local.name);
-							proposal.setCompletion(local.name);
-							proposal.setFlags(local.modifiers);
-							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
-							proposal.setRelevance(relevance);
-							this.requestor.accept(proposal);
-							if(DEBUG) {
-								this.printDebug(proposal);
+							localsFound.add(local);
+	
+							int relevance = computeBaseRelevance();
+							relevance += computeRelevanceForInterestingProposal(local);
+							relevance += computeRelevanceForCaseMatching(token, local.name);
+							relevance += computeRelevanceForExpectingType(local.type);
+							relevance += computeRelevanceForQualification(false);
+							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
+							this.noProposal = false;
+							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+								CompletionProposal proposal = this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
+								proposal.setSignature(
+									local.type == null
+									? createTypeSignature(
+											CharOperation.NO_CHAR,
+											local.declaration.type.toString().toCharArray())
+									: getSignature(local.type));
+								if(local.type == null) {
+									//proposal.setPackageName(null);
+									proposal.setTypeName(local.declaration.type.toString().toCharArray());
+								} else {
+									proposal.setPackageName(local.type.qualifiedPackageName());
+									proposal.setTypeName(local.type.qualifiedSourceName());
+								}
+								proposal.setName(local.name);
+								proposal.setCompletion(local.name);
+								proposal.setFlags(local.modifiers);
+								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+								proposal.setRelevance(relevance);
+								this.requestor.accept(proposal);
+								if(DEBUG) {
+									this.printDebug(proposal);
+								}
 							}
 						}
-					}
-					break;
-
-				case Scope.COMPILATION_UNIT_SCOPE :
-					break done1;
+						break;
+	
+					case Scope.COMPILATION_UNIT_SCOPE :
+						break done1;
+				}
+				currentScope = currentScope.parent;
 			}
-			currentScope = currentScope.parent;
 		}
-
+		
+		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
+		
 		staticsOnly = false;
 		currentScope = scope;
 
-		done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-
-			switch (currentScope.kind) {
-				case Scope.METHOD_SCOPE :
-					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
-					MethodScope methodScope = (MethodScope) currentScope;
-					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
-					break;
-				case Scope.CLASS_SCOPE :
-					ClassScope classScope = (ClassScope) currentScope;
-					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
-					/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
-										findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
-										findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
-										break done;
-									} else { */
-					findFields(
-						token,
-						enclosingType,
-						classScope,
-						fieldsFound,
-						localsFound,
-						staticsOnly,
-						invocationSite,
-						invocationScope,
-						true,
-						true);
-
-					findMethods(
-						token,
-						null,
-						enclosingType,
-						classScope,
-						methodsFound,
-						staticsOnly,
-						false,
-						false,
-						invocationSite,
-						invocationScope,
-						true,
-						false,
-						true);
-					staticsOnly |= enclosingType.isStatic();
-					//				}
-					break;
-
-				case Scope.COMPILATION_UNIT_SCOPE :
-					break done2;
-			}
-			currentScope = currentScope.parent;
-		}
-		
-		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
-		for (int i = 0; i < importBindings.length; i++) {
-			ImportBinding importBinding = importBindings[i];
-			if(importBinding.isValidBinding() && importBinding.isStatic()) {
-				Binding binding = importBinding.resolvedImport;
-				if(binding != null && binding.isValidBinding()) {
-					if(importBinding.onDemand) {
-						if((binding.kind() & Binding.TYPE) != 0) {
-							findFields(
-								token,
-								(ReferenceBinding)binding,
-								scope,
-								fieldsFound,
-								localsFound,
-								true,
-								invocationSite,
-								invocationScope,
-								true,
-								false);
-							
-							findMethods(
-								token,
-								null,
-								(ReferenceBinding)binding,
-								scope,
-								methodsFound,
-								true,
-								false,
-								false,
-								invocationSite,
-								invocationScope,
-								true,
-								false,
-								false);
-						}
-					} else {
-						if ((binding.kind() & Binding.FIELD) != 0) {
+		if(proposeField || proposeMethod) {
+			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+	
+				switch (currentScope.kind) {
+					case Scope.METHOD_SCOPE :
+						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
+						MethodScope methodScope = (MethodScope) currentScope;
+						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+						break;
+					case Scope.CLASS_SCOPE :
+						ClassScope classScope = (ClassScope) currentScope;
+						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
+											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
+											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
+											break done;
+										} else { */
+						if(!insideTypeAnnotation) {
+							if(proposeField) {
 								findFields(
+									token,
+									enclosingType,
+									classScope,
+									fieldsFound,
+									localsFound,
+									staticsOnly,
+									invocationSite,
+									invocationScope,
+									true,
+									true);
+							}
+							if(proposeMethod && !insideAnnotationAttribute) {
+								findMethods(
+									token,
+									null,
+									enclosingType,
+									classScope,
+									methodsFound,
+									staticsOnly,
+									false,
+									false,
+									invocationSite,
+									invocationScope,
+									true,
+									false,
+									true);
+							}
+						}
+						staticsOnly |= enclosingType.isStatic();
+						insideTypeAnnotation = false;
+						//				}
+						break;
+	
+					case Scope.COMPILATION_UNIT_SCOPE :
+						break done2;
+				}
+				currentScope = currentScope.parent;
+			}
+			
+			ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+			for (int i = 0; i < importBindings.length; i++) {
+				ImportBinding importBinding = importBindings[i];
+				if(importBinding.isValidBinding() && importBinding.isStatic()) {
+					Binding binding = importBinding.resolvedImport;
+					if(binding != null && binding.isValidBinding()) {
+						if(importBinding.onDemand) {
+							if((binding.kind() & Binding.TYPE) != 0) {
+								if(proposeField) {
+									findFields(
 										token,
-										new FieldBinding[]{(FieldBinding)binding},
+										(ReferenceBinding)binding,
 										scope,
 										fieldsFound,
 										localsFound,
 										true,
-										((FieldBinding)binding).declaringClass,
 										invocationSite,
 										invocationScope,
 										true,
 										false);
+								}
+								if(proposeMethod && !insideAnnotationAttribute) {
+									findMethods(
+										token,
+										null,
+										(ReferenceBinding)binding,
+										scope,
+										methodsFound,
+										true,
+										false,
+										false,
+										invocationSite,
+										invocationScope,
+										true,
+										false,
+										false);
+								}
+							}
+						} else {
+							if ((binding.kind() & Binding.FIELD) != 0) {
+								if(proposeField) {
+										findFields(
+												token,
+												new FieldBinding[]{(FieldBinding)binding},
+												scope,
+												fieldsFound,
+												localsFound,
+												true,
+												((FieldBinding)binding).declaringClass,
+												invocationSite,
+												invocationScope,
+												true,
+												false);
+								}
+							} else if ((binding.kind() & Binding.METHOD) != 0) {
+								if(proposeMethod && !insideAnnotationAttribute) {
+									MethodBinding methodBinding = (MethodBinding)binding;
+									if(CharOperation.prefixEquals(token, methodBinding.selector))
+										
+									findLocalMethodsOfStaticImports(
+											methodBinding.selector,
+											methodBinding.declaringClass.methods(),
+											scope,
+											methodBinding.declaringClass,
+											invocationSite);
+								}
+							}
 						}
 					}
 				}
@@ -4071,7 +4294,7 @@
 					relevance += computeRelevanceForInterestingProposal();
 					relevance += computeRelevanceForCaseMatching(t, name);
 					relevance += prefixAndSuffixRelevance;
-					relevance += computeRelevanceForRestrictions(false); // no access restriction for variable name
+					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
 					
 					// accept result
 					CompletionEngine.this.noProposal = false;
@@ -4362,6 +4585,25 @@
 					}
 				}
 			}
+		} else if(parent instanceof MemberValuePair) {
+			MemberValuePair memberValuePair = (MemberValuePair) parent;
+			if(memberValuePair.binding != null) {
+				addExpectedType(memberValuePair.binding.returnType);
+			}
+		} else if (parent instanceof NormalAnnotation) {
+			NormalAnnotation annotation = (NormalAnnotation) parent;
+			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+			if(memberValuePairs == null || memberValuePairs.length == 0) {
+				if(annotation.resolvedType instanceof ReferenceBinding) {
+					MethodBinding[] methodBindings =
+						((ReferenceBinding)annotation.resolvedType).availableMethods();
+					if(methodBindings != null &&
+							methodBindings.length == 1 &&
+							CharOperation.equals(methodBindings[0].selector, VALUE)) {
+						addExpectedType(methodBindings[0].returnType);
+					}
+				}
+			}
 		}
 		
 		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
@@ -4518,6 +4760,14 @@
 			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
 		this.expectedTypes[this.expectedTypesPtr] = type;
 	}
+	private void addForbiddenBindings(Binding binding){
+		if (binding == null) return;
+
+		int length = this.forbbidenBindings.length;
+		if (++this.forbbidenBindingsPtr >= length)
+			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
+		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
+	}
 	private void addUninterestingBindings(Binding binding){
 		if (binding == null) return;
 
@@ -4526,7 +4776,31 @@
 			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
 		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
 	}
-	
+
+	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
+		if(scope instanceof ClassScope) {
+			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
+			if(typeDeclaration.superclass == astNode) {
+				this.addForbiddenBindings(typeDeclaration.binding);
+				return scope.parent;
+			}
+			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+			int length = superInterfaces == null ? 0 : superInterfaces.length;
+			for (int i = 0; i < length; i++) {
+				if(superInterfaces[i] == astNode) {
+					this.addForbiddenBindings(typeDeclaration.binding);
+					return scope.parent;
+				}
+			}
+		}
+//		else if(scope instanceof MethodScope) {
+//			MethodScope methodScope = (MethodScope) scope;
+//			if(methodScope.insideTypeAnnotation) {
+//				return methodScope.parent.parent;
+//			}
+//		}
+		return scope;
+	}
 	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
 		
 		StringBuffer completion = new StringBuffer(10);
@@ -4561,7 +4835,7 @@
 		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
 			int relevance = computeBaseRelevance();
 			relevance += computeRelevanceForInterestingProposal();
-			relevance += computeRelevanceForRestrictions(false); // no access restriction for new method
+			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
 			
 			CompletionProposal proposal = this.createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
 			proposal.setDeclarationSignature(getSignature(reference));
@@ -4590,7 +4864,14 @@
 			}
 		}
 	}
-	
+	private boolean isForbidden(Binding binding) {
+		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
+			if(this.forbbidenBindings[i] == binding) {
+				return true;
+			}
+		}
+		return false;
+	}
 	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
 		
 		if(parent instanceof ParameterizedSingleTypeReference) {
@@ -4753,7 +5034,10 @@
 				buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
 				break;
 			case CompletionProposal.METHOD_NAME_REFERENCE :
-				buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
+				buffer.append("METHOD_NAME_REFERENCE"); //$NON-NLS-1$
+				break;
+			case CompletionProposal.ANNOTATION_ATTRIBUTE_REF :
+				buffer.append("ANNOTATION_ATTRIBUT_REF"); //$NON-NLS-1$
 				break;
 			default :
 				buffer.append("PROPOSAL"); //$NON-NLS-1$
@@ -4764,7 +5048,9 @@
 		buffer.append("{\n");//$NON-NLS-1$
 		buffer.append("\tCompletion[").append(proposal.getCompletion() == null ? "null".toCharArray() : proposal.getCompletion()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		buffer.append("\tDeclarationSignature[").append(proposal.getDeclarationSignature() == null ? "null".toCharArray() : proposal.getDeclarationSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buffer.append("\tDeclarationKey[").append(proposal.getDeclarationKey() == null ? "null".toCharArray() : proposal.getDeclarationKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 		buffer.append("\tSignature[").append(proposal.getSignature() == null ? "null".toCharArray() : proposal.getSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		buffer.append("\tKey[").append(proposal.getKey() == null ? "null".toCharArray() : proposal.getKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 //		buffer.append("\tDeclarationPackage[").append(proposal.getDeclarationPackageName() == null ? "null".toCharArray() : proposal.getDeclarationPackageName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 //		buffer.append("\tDeclarationType[").append(proposal.getDeclarationTypeName() == null ? "null".toCharArray() : proposal.getDeclarationTypeName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 //		buffer.append("\tPackage[").append(proposal.getPackageName() == null ? "null".toCharArray() : proposal.getPackageName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java
index 04ca5bc..72a1fe5 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionRequestorWrapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java
index 3565330..035f85a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/IExtendedCompletionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
index 7fcfffe..f242334 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISearchRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,44 +21,54 @@
  */
 public interface ISearchRequestor {
 	/**
-	 * One result of the search consists of a new annotation.
+	 * One result of the search consists of a new type.
 	 *
 	 * NOTE - All package and type names are presented in their readable form:
 	 *    Package names are in the form "a.b.c".
 	 *    Nested type names are in the qualified form "A.I".
 	 *    The default package is represented by an empty array.
 	 */
-	public void acceptAnnotation(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+	public void acceptType(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
 
-	/**
-	 * One result of the search consists of a new class.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.M".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptClass(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
-
-	/**
-	 * One result of the search consists of a new enum.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.I".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptEnum(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
-
-	/**
-	 * One result of the search consists of a new interface.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.I".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptInterface(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//	/**
+//	 * One result of the search consists of a new annotation.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.I".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptAnnotation(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//
+//	/**
+//	 * One result of the search consists of a new class.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.M".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptClass(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//
+//	/**
+//	 * One result of the search consists of a new enum.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.I".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptEnum(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
+//
+//	/**
+//	 * One result of the search consists of a new interface.
+//	 *
+//	 * NOTE - All package and type names are presented in their readable form:
+//	 *    Package names are in the form "a.b.c".
+//	 *    Nested type names are in the qualified form "A.I".
+//	 *    The default package is represented by an empty array.
+//	 */
+//	public void acceptInterface(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction);
 
 	/**
 	 * One result of the search consists of a new package.
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
index cf86981..ff00039 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -27,9 +27,9 @@
 	 * @param isDeclaration boolean
 	 *  	Answer if the selected type is a declaration
 	 *  
-	 * @param uniqueKey
-	 *  	unique key of the selected type if it is a
-	 *  	parameterized type ({@link org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()})
+	 * @param genericTypeSignature
+	 *  	genric type signature of the selected type if it is a
+	 *  	parameterized type
 	 * 
 	 * @param start
 	 *  	Start of the selection
@@ -42,78 +42,12 @@
 	 *    Nested type names are in the qualified form "A.M".
 	 *    The default package is represented by an empty array.
 	 */
-	void acceptAnnotation(
+	void acceptType(
 		char[] packageName,
 		char[] annotationName,
+		int modifiers,
 		boolean isDeclaration,
-		char[] uniqueKey,
-		int start,
-		int end);
-	/**
-	 * Code assist notification of a class selection.
-	 * @param packageName char[]
-	 * 		Declaring package name of the class.
-	 * 
-	 * @param className char[]
-	 * 		Name of the class.
-	 * 
-	 * @param isDeclaration boolean
-	 *  	Answer if the selected method is a declaration
-	 *  
-	 * @param uniqueKey
-	 *  	unique key of the selected type if it is a
-	 *  	parameterized type ({@link org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()})
-	 * 
-	 * @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".
-	 *    Nested type names are in the qualified form "A.M".
-	 *    The default package is represented by an empty array.
-	 */
-	void acceptClass(
-		char[] packageName,
-		char[] className,
-		boolean isDeclaration,
-		char[] uniqueKey,
-		int start,
-		int end);
-	
-	/**
-	 * Code assist notification of a enum selection.
-	 * @param packageName char[]
-	 * 		Declaring package name of the type.
-	 * 
-	 * @param enumName char[]
-	 * 		Name of the class.
-	 * 
-	 * @param isDeclaration boolean
-	 *  	Answer if the selected type is a declaration
-	 *  
-	 * @param uniqueKey
-	 *  	unique key of the selected type if it is a
-	 *  	parameterized type ({@link org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()})
-	 * 
-	 * @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".
-	 *    Nested type names are in the qualified form "A.M".
-	 *    The default package is represented by an empty array.
-	 */
-	void acceptEnum(
-		char[] packageName,
-		char[] enumName,
-		boolean isDeclaration,
-		char[] uniqueKey,
+		char[] genericTypeSignature,
 		int start,
 		int end);
 
@@ -146,8 +80,7 @@
 	 *  	Answer if the selected field is a declaration
 	 * 
 	 * @param uniqueKey
-	 *  	unique key of the selected field if the field's type is a
-	 *  	parameterized type ({@link org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()})
+	 *  	unique key of this field
 	 *  
 	 * @param start
 	 *  	Start of the selection
@@ -170,40 +103,6 @@
 		int end);
 
 	/**
-	 * Code assist notification of an interface selection.
-	 * @param packageName char[]
-	 * 		Declaring package name of the interface.
-	 * 
-	 * @param interfaceName char[]
-	 * 		Name of the interface.
-	 * 
-	 * @param isDeclaration boolean
-	 *  	Answer if the selected method is a declaration
-	 *  
-	 * @param uniqueKey
-	 *  	unique key of the selected type if it is a
-	 *  	parameterized type ({@link org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()})
-	 * 
-	 * @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".
-	 *    Nested type names are in the qualified form "A.I".
-	 *    The default package is represented by an empty array.
-	 */
-	void acceptInterface(
-		char[] packageName,
-		char[] interfaceName,
-		boolean isDeclaration,
-		char[] uniqueKey,
-		int start,
-		int end);
-
-	/**
 	 * Code assist notification of a method selection.
 	 * @param declaringTypePackageName char[]
 	 * 		Name of the package in which the type that contains this new method is declared.
@@ -237,9 +136,8 @@
 	 *  	Answer if the selected method is a declaration
 	 * 
 	 * @param uniqueKey
-	 *  	unique key of the selected method if it is a
-	 *  	parameterized method ({@link org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()})
-	 *  
+	 *  	unique key of the method
+	 *
 	 * @param start
 	 *  	Start of the selection
 	 * 
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java
new file mode 100644
index 0000000..9ca3a35
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionContext.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist;
+
+
+/**
+ * Internal completion context
+ * @since 3.1
+ */
+public class InternalCompletionContext {
+	protected char[][] expectedTypesSignatures;
+	protected char[][] expectedTypesKeys;
+	
+	protected void setExpectedTypesSignatures(char[][] expectedTypesSignatures) {
+		this.expectedTypesSignatures = expectedTypesSignatures;
+	}
+	
+	protected void setExpectedTypesKeys(char[][] expectedTypesKeys) {
+		this.expectedTypesKeys = expectedTypesKeys;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
index eb25366..f16a7b1 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalCompletionProposal.java
@@ -1,15 +1,16 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.codeassist;
 
+import org.eclipse.jdt.core.IAccessRule;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
@@ -45,6 +46,8 @@
 	protected char[][] parameterPackageNames;
 	protected char[][] parameterTypeNames;
 	
+	protected int accessibility = IAccessRule.K_ACCESSIBLE;
+	
 	protected char[][] findMethodParameterNames(char[] signatureType, char[] selector, char[][] paramTypeNames){
 		if(signatureType == null) return null;
 		
@@ -246,4 +249,8 @@
 	protected void setParameterTypeNames(char[][] parameterTypeNames) {
 		this.parameterTypeNames = parameterTypeNames;
 	}
+	
+	protected void setAccessibility(int kind) {
+		this.accessibility = kind;
+	}
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
index 94c46fa..51c6233 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,8 +20,10 @@
 	int R_EXACT_EXPECTED_TYPE = 30;
 	int R_INTERFACE = 20;
 	int R_CLASS = 20;
+	int R_ENUM = 20;
 	int R_ANNOTATION = 20;
 	int R_EXCEPTION = 20;
+	int R_ENUM_CONSTANT = 20;
 	int R_ABSTRACT_METHOD = 20;
 	int R_NON_STATIC = 11;
 	int R_UNQUALIFIED = 3;
@@ -32,5 +34,6 @@
 	int R_NAME_SUFFIX = 3;
 	int R_NON_STATIC_OVERIDE = 3;
 	int R_NON_RESTRICTED = 3;
+	int R_TRUE_OR_FALSE = 1;
 	
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
index 5622632..610fe4c 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,6 +41,7 @@
 public final class SelectionEngine extends Engine implements ISearchRequestor {
 
 	public static boolean DEBUG = false;
+	public static boolean PERF = false;
 	
 	SelectionParser parser;
 	ISelectionRequestor requestor;
@@ -52,9 +53,13 @@
 	private char[] selectedIdentifier;
 	
 	private char[][][] acceptedClasses;
+	private int[] acceptedClassesModifiers;
 	private char[][][] acceptedInterfaces;
+	private int[] acceptedInterfacesModifiers;
 	private char[][][] acceptedEnums;
+	private int[] acceptedEnumsModifiers;
 	private char[][][] acceptedAnnotations;
+	private int[] acceptedAnnotationsModifiers;
 	int acceptedClassesCount;
 	int acceptedInterfacesCount;
 	int acceptedEnumsCount;
@@ -126,144 +131,96 @@
 		this.parser = new SelectionParser(problemReporter);
 	}
 
-	public void acceptAnnotation(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction) {
+	public void acceptType(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction) {
 		if (CharOperation.equals(typeName, this.selectedIdentifier)) {
 			if(mustQualifyType(packageName, typeName)) {
-				char[][] acceptedAnnotation = new char[2][];
-				acceptedAnnotation[0] = packageName;
-				acceptedAnnotation[1] = typeName;
-				
-				if(this.acceptedAnnotations == null) {
-					this.acceptedAnnotations = new char[10][][];
-					this.acceptedAnnotationsCount = 0;
+				int length = 0;
+				int kind = modifiers & (IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation);
+				switch (kind) {
+					case IConstants.AccAnnotation:
+					case IConstants.AccAnnotation | IConstants.AccInterface:
+						char[][] acceptedAnnotation = new char[2][];
+						acceptedAnnotation[0] = packageName;
+						acceptedAnnotation[1] = typeName;
+						
+						if(this.acceptedAnnotations == null) {
+							this.acceptedAnnotations = new char[10][][];
+							this.acceptedAnnotationsModifiers = new int[10];
+							this.acceptedAnnotationsCount = 0;
+						}
+						length = this.acceptedAnnotations.length;
+						if(length == this.acceptedAnnotationsCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedAnnotations, 0, this.acceptedAnnotations = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedAnnotationsModifiers, 0, this.acceptedAnnotationsModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedAnnotationsModifiers[this.acceptedAnnotationsCount] = modifiers;
+						this.acceptedAnnotations[this.acceptedAnnotationsCount++] = acceptedAnnotation;
+						break;
+					case IConstants.AccEnum:
+						char[][] acceptedEnum = new char[2][];
+						acceptedEnum[0] = packageName;
+						acceptedEnum[1] = typeName;
+						
+						if(this.acceptedEnums == null) {
+							this.acceptedEnums = new char[10][][];
+							this.acceptedEnumsModifiers = new int[10];
+							this.acceptedEnumsCount = 0;
+						}
+						length = this.acceptedEnums.length;
+						if(length == this.acceptedEnumsCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedEnums, 0, this.acceptedEnums = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedEnumsModifiers, 0, this.acceptedEnumsModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedEnumsModifiers[this.acceptedEnumsCount] = modifiers;
+						this.acceptedEnums[this.acceptedEnumsCount++] = acceptedEnum;
+						break;
+					case IConstants.AccInterface:
+						char[][] acceptedInterface= new char[2][];
+						acceptedInterface[0] = packageName;
+						acceptedInterface[1] = typeName;
+						
+						if(this.acceptedInterfaces == null) {
+							this.acceptedInterfaces = new char[10][][];
+							this.acceptedInterfacesModifiers = new int[10];
+							this.acceptedInterfacesCount = 0;
+						}
+						length = this.acceptedInterfaces.length;
+						if(length == this.acceptedInterfacesCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedInterfaces, 0, this.acceptedInterfaces = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedInterfacesModifiers, 0, this.acceptedInterfacesModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedInterfacesModifiers[this.acceptedInterfacesCount] = modifiers;
+						this.acceptedInterfaces[this.acceptedInterfacesCount++] = acceptedInterface;
+						break;
+					default:
+						char[][] acceptedClass = new char[2][];
+						acceptedClass[0] = packageName;
+						acceptedClass[1] = typeName;
+						
+						if(this.acceptedClasses == null) {
+							this.acceptedClasses = new char[10][][];
+							this.acceptedClassesModifiers = new int[10];
+							this.acceptedClassesCount = 0;
+						}
+						length = this.acceptedClasses.length;
+						if(length == this.acceptedClassesCount) {
+							int newLength = (length + 1)* 2;
+							System.arraycopy(this.acceptedClasses, 0, this.acceptedClasses = new char[newLength][][], 0, length);
+							System.arraycopy(this.acceptedClassesModifiers, 0, this.acceptedClassesModifiers = new int[newLength], 0, length);
+						}
+						this.acceptedClassesModifiers[this.acceptedClassesCount] = modifiers;
+						this.acceptedClasses[this.acceptedClassesCount++] = acceptedClass;
+						break;
 				}
-				int length = this.acceptedAnnotations.length;
-				if(length == this.acceptedAnnotationsCount) {
-					System.arraycopy(this.acceptedAnnotations, 0, this.acceptedAnnotations = new char[(length + 1)* 2][][], 0, length);
-				}
-				this.acceptedAnnotations[this.acceptedAnnotationsCount++] = acceptedAnnotation;
-				
 			} else {
 				this.noProposal = false;
-				this.requestor.acceptAnnotation(
+				this.requestor.acceptType(
 					packageName,
 					typeName,
-					false,
-					null,
-					this.actualSelectionStart,
-					this.actualSelectionEnd);
-				this.acceptedAnswer = true;
-			}
-		}
-	}
-	
-	/**
-	 * One result of the search consists of a new class.
-	 * @param packageName char[]
-	 * @param className char[]
-	 * @param modifiers int
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.M".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptClass(char[] packageName, char[] className, int modifiers, AccessRestriction accessRestriction) {
-		if (CharOperation.equals(className, this.selectedIdentifier)) {
-			if(mustQualifyType(packageName, className)) {
-				char[][] acceptedClass = new char[2][];
-				acceptedClass[0] = packageName;
-				acceptedClass[1] = className;
-				
-				if(this.acceptedClasses == null) {
-					this.acceptedClasses = new char[10][][];
-					this.acceptedClassesCount = 0;
-				}
-				int length = this.acceptedClasses.length;
-				if(length == this.acceptedClassesCount) {
-					System.arraycopy(this.acceptedClasses, 0, this.acceptedClasses = new char[(length + 1)* 2][][], 0, length);
-				}
-				this.acceptedClasses[this.acceptedClassesCount++] = acceptedClass;
-				
-			} else {
-				this.noProposal = false;
-				this.requestor.acceptClass(
-					packageName,
-					className,
-					false,
-					null,
-					this.actualSelectionStart,
-					this.actualSelectionEnd);
-				this.acceptedAnswer = true;
-			}
-		}
-	}
-
-	public void acceptEnum(char[] packageName, char[] typeName, int modifiers, AccessRestriction accessRestriction) {
-		if (CharOperation.equals(typeName, this.selectedIdentifier)) {
-			if(mustQualifyType(packageName, typeName)) {
-				char[][] acceptedEnum = new char[2][];
-				acceptedEnum[0] = packageName;
-				acceptedEnum[1] = typeName;
-				
-				if(this.acceptedEnums == null) {
-					this.acceptedEnums = new char[10][][];
-					this.acceptedEnumsCount = 0;
-				}
-				int length = this.acceptedEnums.length;
-				if(length == this.acceptedEnumsCount) {
-					System.arraycopy(this.acceptedEnums, 0, this.acceptedEnums = new char[(length + 1)* 2][][], 0, length);
-				}
-				this.acceptedEnums[this.acceptedEnumsCount++] = acceptedEnum;
-				
-			} else {
-				this.noProposal = false;
-				this.requestor.acceptEnum(
-					packageName,
-					typeName,
-					false,
-					null,
-					this.actualSelectionStart,
-					this.actualSelectionEnd);
-				this.acceptedAnswer = true;
-			}
-		}
-	}
-	/**
-	 * One result of the search consists of a new interface.
-	 *
-	 * NOTE - All package and type names are presented in their readable form:
-	 *    Package names are in the form "a.b.c".
-	 *    Nested type names are in the qualified form "A.I".
-	 *    The default package is represented by an empty array.
-	 */
-	public void acceptInterface(
-		char[] packageName,
-		char[] interfaceName,
-		int modifiers,
-		AccessRestriction accessRestriction) {
-
-		if (CharOperation.equals(interfaceName, this.selectedIdentifier)) {
-			if(mustQualifyType(packageName, interfaceName)) {
-				char[][] acceptedInterface= new char[2][];
-				acceptedInterface[0] = packageName;
-				acceptedInterface[1] = interfaceName;
-				
-				if(this.acceptedInterfaces == null) {
-					this.acceptedInterfaces = new char[10][][];
-					this.acceptedInterfacesCount = 0;
-				}
-				int length = this.acceptedInterfaces.length;
-				if(length == this.acceptedInterfacesCount) {
-					System.arraycopy(this.acceptedInterfaces, 0, this.acceptedInterfaces = new char[(length + 1) * 2][][], 0, length);
-				}
-				this.acceptedInterfaces[this.acceptedInterfacesCount++] = acceptedInterface;
-				
-			} else {
-				this.noProposal = false;
-				this.requestor.acceptInterface(
-					packageName,
-					interfaceName,
+					modifiers,
 					false,
 					null,
 					this.actualSelectionStart,
@@ -290,60 +247,68 @@
 			this.acceptedAnswer = true;
 			for (int i = 0; i < this.acceptedClassesCount; i++) {
 				this.noProposal = false;
-				this.requestor.acceptClass(
+				this.requestor.acceptType(
 					this.acceptedClasses[i][0],
 					this.acceptedClasses[i][1],
+					this.acceptedClassesModifiers[i],
 					false,
 					null,
 					this.actualSelectionStart,
 					this.actualSelectionEnd);
 			}
 			this.acceptedClasses = null;
+			this.acceptedClassesModifiers = null;
 			this.acceptedClassesCount = 0;
 		}
 		if(this.acceptedInterfaces != null){
 			this.acceptedAnswer = true;
 			for (int i = 0; i < this.acceptedInterfacesCount; i++) {
 				this.noProposal = false;
-				this.requestor.acceptInterface(
+				this.requestor.acceptType(
 					this.acceptedInterfaces[i][0],
 					this.acceptedInterfaces[i][1],
+					this.acceptedInterfacesModifiers[i],
 					false,
 					null,
 					this.actualSelectionStart,
 					this.actualSelectionEnd);
 			}
 			this.acceptedInterfaces = null;
+			this.acceptedInterfacesModifiers = null;
 			this.acceptedInterfacesCount = 0;
 		}
 		if(this.acceptedAnnotations != null){
 			this.acceptedAnswer = true;
 			for (int i = 0; i < this.acceptedAnnotationsCount; i++) {
 				this.noProposal = false;
-				this.requestor.acceptAnnotation(
+				this.requestor.acceptType(
 					this.acceptedAnnotations[i][0],
 					this.acceptedAnnotations[i][1],
+					this.acceptedAnnotationsModifiers[i],
 					false,
 					null,
 					this.actualSelectionStart,
 					this.actualSelectionEnd);
 			}
 			this.acceptedAnnotations = null;
+			this.acceptedAnnotationsModifiers = null;
 			this.acceptedAnnotationsCount = 0;
 		}
 		if(this.acceptedEnums != null){
 			this.acceptedAnswer = true;
 			for (int i = 0; i < this.acceptedEnumsCount; i++) {
 				this.noProposal = false;
-				this.requestor.acceptEnum(
+				this.requestor.acceptType(
 					this.acceptedEnums[i][0],
 					this.acceptedEnums[i][1],
+					this.acceptedEnumsModifiers[i],
 					false,
 					null,
 					this.actualSelectionStart,
 					this.actualSelectionEnd);
 			}
 			this.acceptedEnums = null;
+			this.acceptedEnumsModifiers = null;
 			this.acceptedEnumsCount = 0;
 		}
 	}
@@ -367,7 +332,7 @@
 			int nextCharacterPosition = selectionStart;
 			char currentCharacter = ' ';
 			try {
-				while(currentPosition > 0){
+				lineLoop: while(currentPosition > 0){
 					
 					if(source[currentPosition] == '\\' && source[currentPosition+1] == 'u') {
 						int pos = currentPosition + 2;
@@ -393,8 +358,13 @@
 						nextCharacterPosition = currentPosition+1;
 					}
 					
-					if(currentCharacter == '\r' || currentCharacter == '\n') {
-						break;
+					switch(currentCharacter) {
+						case '\r':
+						case '\n':
+						case '/':
+						case '"':
+						case '\'':
+							break lineLoop;
 					}
 					currentPosition--;
 				}
@@ -410,14 +380,16 @@
 				} catch (InvalidInputException e) {
 					return false;
 				}
-				if((token == TerminalTokens.TokenNamethis ||
-					token == TerminalTokens.TokenNamesuper ||
-					token == TerminalTokens.TokenNameIdentifier) &&
-					scanner.startPosition <= selectionStart &&
-					selectionStart <= scanner.currentPosition) {
-					lastIdentifierStart = scanner.startPosition;
-					lastIdentifierEnd = scanner.currentPosition - 1;
-					lastIdentifier = scanner.getCurrentTokenSource();
+				switch (token) {
+					case TerminalTokens.TokenNamethis:
+					case TerminalTokens.TokenNamesuper:
+					case TerminalTokens.TokenNameIdentifier:
+						if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) {
+							lastIdentifierStart = scanner.startPosition;
+							lastIdentifierEnd = scanner.currentPosition - 1;
+							lastIdentifier = scanner.getCurrentTokenSource();
+						}
+						break;
 				}
 			} while (token != TerminalTokens.TokenNameEOF);
 		} else {
@@ -457,6 +429,10 @@
 							if(!checkTypeArgument(scanner))
 								return false;
 							break;
+						case TerminalTokens.TokenNameAT:
+							if(scanner.startPosition != scanner.initialPosition)
+								return false;
+							break;
 						default :
 							return false;
 					}
@@ -540,55 +516,6 @@
 		
 		return false;
 	}
-
-	private void completeLocalTypes(Binding binding){
-		switch(binding.kind()) {
-			case Binding.PARAMETERIZED_TYPE :
-			case Binding.RAW_TYPE :
-				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) binding;
-				this.completeLocalTypes(parameterizedTypeBinding.type);
-				TypeBinding[] args = parameterizedTypeBinding.arguments;
-				int length = args == null ? 0 : args.length;
-				for (int i = 0; i < length; i++) {
-					this.completeLocalTypes(args[i]);
-				}
-				break;
-			case Binding.TYPE :
-			case Binding.GENERIC_TYPE :
-				if(binding instanceof LocalTypeBinding) {
-					LocalTypeBinding localTypeBinding = (LocalTypeBinding) binding;
-					if(localTypeBinding.constantPoolName() == null) {
-						char[] constantPoolName = this.unitScope.computeConstantPoolName(localTypeBinding);
-						localTypeBinding.setConstantPoolName(constantPoolName);
-					}
-				}
-				TypeBinding typeBinding = (TypeBinding) binding;
-				ReferenceBinding enclosingType = typeBinding.enclosingType();
-				if(enclosingType != null) {
-					this.completeLocalTypes(enclosingType);
-				}
-				break;
-			case Binding.ARRAY_TYPE :
-				ArrayBinding arrayBinding = (ArrayBinding) binding;
-				this.completeLocalTypes(arrayBinding.leafComponentType);
-			case Binding.WILDCARD_TYPE :
-			case Binding.TYPE_PARAMETER :
-				break;	
-			case Binding.FIELD :
-				FieldBinding fieldBinding = (FieldBinding) binding;
-				this.completeLocalTypes(fieldBinding.declaringClass);
-				this.completeLocalTypes(fieldBinding.type);
-				break;	
-			case Binding.METHOD :
-				MethodBinding methodBinding = (MethodBinding) binding;
-				this.completeLocalTypes(methodBinding.returnType);
-				TypeBinding[] parameters = methodBinding.parameters;
-				for(int i = 0, max = parameters == null ? 0 : parameters.length; i < max; i++) {
-					this.completeLocalTypes(parameters[i]);
-				}
-				break;
-		}
-	}
 	
 	public AssistParser getParser() {
 		return this.parser;
@@ -638,8 +565,14 @@
 			System.out.println("SELECTION - Source :"); //$NON-NLS-1$
 			System.out.println(source);
 		}
-		if (!checkSelection(source, selectionSourceStart, selectionSourceEnd))
+		if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) {
 			return;
+		}
+		if (DEBUG) {
+			System.out.print("SELECTION - Checked : \""); //$NON-NLS-1$
+			System.out.print(new String(source, actualSelectionStart, actualSelectionEnd-actualSelectionStart+1));
+			System.out.println('"');
+		}
 		try {
 			this.acceptedAnswer = false;
 			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
@@ -669,6 +602,23 @@
 							this.noProposal = false;
 							this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
 							this.nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), this);
+							
+							if(importReference.isStatic()) {
+								this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+								if ((this.unitScope = parsedUnit.scope) != null) {
+									int tokenCount = tokens.length;
+									char[] lastToken = tokens[tokenCount - 1];
+									char[][] qualifierTokens = CharOperation.subarray(tokens, 0, tokenCount - 1);
+									
+									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
+									if(binding != null && binding instanceof ReferenceBinding) {
+										ReferenceBinding ref = (ReferenceBinding) binding;
+										selectStaticFieldFromStaticImport(parsedUnit, lastToken, ref);
+										selectStaticMethodFromStaticImport(parsedUnit, lastToken, ref);
+									}
+								}
+							}
+							
 							// accept qualified types only if no unqualified type was accepted
 							if(!this.acceptedAnswer) {
 								acceptQualifiedTypes();
@@ -745,6 +695,52 @@
 		}
 	}
 
+	private void selectStaticFieldFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
+		int fieldLength = lastToken.length;
+		FieldBinding[] fields = ref.fields();
+		next : for (int j = 0; j < fields.length; j++) {
+			FieldBinding field = fields[j];
+			
+			if (fieldLength > field.name.length)
+				continue next;
+			
+			if (field.isSynthetic())
+				continue next;
+
+			if (!field.isStatic())
+				continue next;
+
+			if (!CharOperation.equals(lastToken, field.name, true))
+				continue next;
+			
+			this.selectFrom(field, parsedUnit, false);
+		}
+	}
+	
+	private void selectStaticMethodFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
+		int methodLength = lastToken.length;
+		MethodBinding[] methods = ref.methods();
+		next : for (int j = 0; j < methods.length; j++) {
+			MethodBinding method = methods[j];
+			
+			if (method.isSynthetic()) continue next;
+
+			if (method.isDefaultAbstract())	continue next;
+
+			if (method.isConstructor()) continue next;
+
+			if (!method.isStatic()) continue next;
+
+			if (methodLength > method.selector.length)
+				continue next;
+
+			if (!CharOperation.equals(lastToken, method.selector, true))
+				continue next;
+			
+			this.selectFrom(method, parsedUnit, false);
+		}
+	}
+
 	private void selectFrom(Binding binding, CompilationUnitDeclaration parsedUnit, boolean isDeclaration) {
 		if(binding instanceof TypeVariableBinding) {
 			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) binding;
@@ -766,7 +762,9 @@
 				this.requestor.acceptMethodTypeParameter(
 					enclosingMethod.declaringClass.qualifiedPackageName(),
 					enclosingMethod.declaringClass.qualifiedSourceName(),
-					enclosingMethod.selector,
+					enclosingMethod.isConstructor()
+							? enclosingMethod.declaringClass.sourceName()
+							: enclosingMethod.selector,
 					enclosingMethod.sourceStart(),
 					enclosingMethod.sourceEnd(),
 					typeVariableBinding.sourceName(),
@@ -784,52 +782,18 @@
 			if (typeBinding == null) return;
 			if (isLocal(typeBinding) && this.requestor instanceof SelectionRequestor) {
 				this.noProposal = false;
-				if(typeBinding.isParameterizedType() || typeBinding.isRawType()) {
-					completeLocalTypes(typeBinding);
-				}
 				((SelectionRequestor)this.requestor).acceptLocalType(typeBinding);
 			} else {
 				this.noProposal = false;
-				
-				char[] genericTypeSignature = null;
-				if(typeBinding.isParameterizedType() || typeBinding.isRawType()) {
-					completeLocalTypes(typeBinding);
-					genericTypeSignature = typeBinding.computeUniqueKey();
-				}
-				if (typeBinding.isAnnotationType()) {
-					this.requestor.acceptAnnotation(
-						typeBinding.qualifiedPackageName(),
-						typeBinding.qualifiedSourceName(),
-						false,
-						genericTypeSignature,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-				} else if (typeBinding.isInterface()) {
-					this.requestor.acceptInterface(
-						typeBinding.qualifiedPackageName(),
-						typeBinding.qualifiedSourceName(),
-						false,
-						genericTypeSignature,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-				} else if (typeBinding.isEnum()) {
-					this.requestor.acceptEnum(
-						typeBinding.qualifiedPackageName(),
-						typeBinding.qualifiedSourceName(),
-						false,
-						genericTypeSignature,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-				} else {
-					this.noProposal = false;
-					this.requestor.acceptClass(
-						typeBinding.qualifiedPackageName(),
-						typeBinding.qualifiedSourceName(),
-						false,
-						genericTypeSignature,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-				}
+
+				this.requestor.acceptType(
+					typeBinding.qualifiedPackageName(),
+					typeBinding.qualifiedSourceName(),
+					typeBinding.modifiers,
+					false,
+					typeBinding.computeUniqueKey(),
+					this.actualSelectionStart,
+					this.actualSelectionEnd);
 			}
 			this.acceptedAnswer = true;
 		} else
@@ -848,16 +812,8 @@
 				this.noProposal = false;
 				ReferenceBinding declaringClass = methodBinding.declaringClass;
 				if (isLocal(declaringClass) && this.requestor instanceof SelectionRequestor) {
-					if(methodBinding instanceof ParameterizedMethodBinding) {
-						completeLocalTypes(methodBinding);
-					}
 					((SelectionRequestor)this.requestor).acceptLocalMethod(methodBinding);
 				} else {
-					char[] uniqueKey = null;
-					if(methodBinding instanceof ParameterizedMethodBinding) {
-						completeLocalTypes(methodBinding);
-						uniqueKey = methodBinding.computeUniqueKey();
-					}
 					this.requestor.acceptMethod(
 						declaringClass.qualifiedPackageName(),
 						declaringClass.qualifiedSourceName(),
@@ -870,7 +826,7 @@
 						parameterSignatures,
 						methodBinding.isConstructor(), 
 						isDeclaration,
-						uniqueKey,
+						methodBinding.computeUniqueKey(),
 						this.actualSelectionStart,
 						this.actualSelectionEnd);
 				}
@@ -882,22 +838,14 @@
 					if (declaringClass != null) { // arraylength
 						this.noProposal = false;
 						if (isLocal(declaringClass) && this.requestor instanceof SelectionRequestor) {
-							if(fieldBinding instanceof ParameterizedFieldBinding) {
-								completeLocalTypes(fieldBinding.declaringClass);
-							}
 							((SelectionRequestor)this.requestor).acceptLocalField(fieldBinding);
 						} else {
-							char[] uniqueKey = null;
-							if(fieldBinding instanceof ParameterizedFieldBinding) {
-								completeLocalTypes(fieldBinding.declaringClass);
-								uniqueKey = fieldBinding.computeUniqueKey();
-							}
 							this.requestor.acceptField(
 								declaringClass.qualifiedPackageName(),
 								declaringClass.qualifiedSourceName(),
 								fieldBinding.name,
 								false,
-								uniqueKey,
+								fieldBinding.computeUniqueKey(),
 								this.actualSelectionStart,
 								this.actualSelectionEnd);
 						}
@@ -1144,44 +1092,17 @@
 				qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
 				enclosingType = enclosingType.enclosingType;
 			}
-			switch (typeDeclaration.kind()) {
-				case IGenericType.CLASS_DECL :
-					this.requestor.acceptClass(
-						packageName,
-						qualifiedSourceName,
-						true,
-						null,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-					break;
-				case IGenericType.INTERFACE_DECL :
-					this.requestor.acceptInterface(
-						packageName,
-						qualifiedSourceName,
-						true,
-						null,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-					break;
-				case IGenericType.ENUM_DECL :
-					this.requestor.acceptEnum(
-						packageName,
-						qualifiedSourceName,
-						true,
-						null,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-					break;
-				case IGenericType.ANNOTATION_TYPE_DECL :
-					this.requestor.acceptAnnotation(
-						packageName,
-						qualifiedSourceName,
-						true,
-						null,
-						this.actualSelectionStart,
-						this.actualSelectionEnd);
-					break;
-			}			
+			char[] uniqueKey = typeDeclaration.binding != null ? typeDeclaration.binding.computeUniqueKey() : null;
+			
+			this.requestor.acceptType(
+				packageName,
+				qualifiedSourceName,
+				typeDeclaration.modifiers,
+				true,
+				uniqueKey,
+				this.actualSelectionStart,
+				this.actualSelectionEnd);
+			
 			this.noProposal = false;
 			return true;
 		}
@@ -1200,13 +1121,13 @@
 					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
 					enclosingType = enclosingType.enclosingType;
 				}
-				
+				FieldDeclaration field = fields[i];
 				this.requestor.acceptField(
 					packageName,
 					qualifiedSourceName,
-					fields[i].name,
+					field.name,
 					true,
-					null,
+					field.binding != null ? field.binding.computeUniqueKey() : null,
 					this.actualSelectionStart,
 					this.actualSelectionEnd);
 
@@ -1237,7 +1158,7 @@
 					null, // SelectionRequestor does not need of parameters type for method declaration
 					method.isConstructor(),
 					true,
-					null,
+					method.binding != null ? method.binding.computeUniqueKey() : null,
 					this.actualSelectionStart,
 					this.actualSelectionEnd);
 				
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
index 71fd1ca..a7ae738 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeDetector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -152,6 +152,12 @@
 	public void endVisit(UnaryExpression unaryExpression, BlockScope scope) {
 		endVisit(unaryExpression);
 	}
+	public void endVisit(MemberValuePair pair, BlockScope scope) {
+		endVisit(pair);
+	}
+	public void endVisit(MemberValuePair pair, CompilationUnitScope scope) {
+		endVisit(pair);
+	}
 	public boolean visit(AllocationExpression allocationExpression, BlockScope scope) {
 		return this.visit(allocationExpression);
 	}
@@ -266,7 +272,12 @@
 	public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
 		return this.visit(unaryExpression);
 	}
-	
+	public boolean visit(MemberValuePair pair, BlockScope scope) {
+		return this.visit(pair);
+	}
+	public boolean visit(MemberValuePair pair, CompilationUnitScope scope) {
+		return this.visit(pair);
+	}
 	private void endVisit(ASTNode astNode) {
 		if(this.result && this.parent == null && astNode != this.searchedNode) {
 			if(!(astNode instanceof AllocationExpression && ((AllocationExpression) astNode).type == this.searchedNode)
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java
index 43e6d33..8fbd908 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionNodeFound.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,18 +19,26 @@
 	public ASTNode astNode;
 	public Binding qualifiedBinding;
 	public Scope scope;
+	public boolean insideTypeAnnotation = false;
 
 	private static final long serialVersionUID = 6981437684184091462L; // backward compatible
 	
 public CompletionNodeFound() {
-	this(null, null, null); // we found a problem in the completion node
+	this(null, null, null, false); // we found a problem in the completion node
 }
 public CompletionNodeFound(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+	this(astNode, qualifiedBinding, scope, false);
+}
+public CompletionNodeFound(ASTNode astNode, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) {
 	this.astNode = astNode;
 	this.qualifiedBinding = qualifiedBinding;
 	this.scope = scope;
+	this.insideTypeAnnotation = insideTypeAnnotation;
 }
 public CompletionNodeFound(ASTNode astNode, Scope scope) {
-	this(astNode, null, scope);
+	this(astNode, null, scope, false);
+}
+public CompletionNodeFound(ASTNode astNode, Scope scope, boolean insideTypeAnnotation) {
+	this(astNode, null, scope, insideTypeAnnotation);
 }
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationMemberValuePair.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationMemberValuePair.java
new file mode 100644
index 0000000..ea119ce
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationMemberValuePair.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class CompletionOnAnnotationMemberValuePair extends NormalAnnotation {
+	public MemberValuePair completedMemberValuePair;
+	public CompletionOnAnnotationMemberValuePair(TypeReference type, int sourceStart, MemberValuePair[] memberValuePairs, MemberValuePair completedMemberValuePair) {
+		super(type, sourceStart);
+		this.memberValuePairs = memberValuePairs;
+		this.completedMemberValuePair = completedMemberValuePair;
+	}
+	
+	public TypeBinding resolveType(BlockScope scope) {
+		super.resolveType(scope);
+		
+		if (this.resolvedType == null || !this.resolvedType.isValidBinding()) {
+			throw new CompletionNodeFound();
+		} else {
+			throw new CompletionNodeFound(this.completedMemberValuePair, scope);
+		}
+	}
+	
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		output.append('@');
+		this.type.printExpression(0, output);
+		output.append('(');
+		if (this.memberValuePairs != null) {
+			for (int i = 0, max = this.memberValuePairs.length; i < max; i++) {
+				if (i > 0) {
+					output.append(',');
+				}
+				this.memberValuePairs[i].print(indent, output);
+			}
+			output.append(',');
+		}
+		this.completedMemberValuePair.print(indent, output);
+		output.append(')');
+		
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java
index 9bf48e9..9782fcf 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnAnnotationOfType.java
@@ -1,26 +1,25 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.codeassist.complete;
 
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 
 public class CompletionOnAnnotationOfType extends TypeDeclaration {
-	public CompletionOnAnnotationOfType(CompilationResult compilationResult, Annotation annotation){
+	public CompletionOnAnnotationOfType(char[] typeName, CompilationResult compilationResult, Annotation annotation){
 		super(compilationResult);
 		this.sourceEnd = annotation.sourceEnd;
 		this.sourceStart = annotation.sourceEnd;
-		this.name = CharOperation.NO_CHAR;
+		this.name = typeName;
 		this.annotations = new Annotation[]{annotation};
 	}
 	
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java
index bfe8798..9bcd98d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnArgumentName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java
index 9e5e4fa..919d576 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassLiteralAccess.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassReference.java
index 3613f5e..9ff248c 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnClassReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExceptionReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExceptionReference.java
index c424dc4..45bc49e 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExceptionReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExceptionReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java
index 234d7ba..d91bde8 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnExplicitConstructorCall.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java
index d918d55..f177318 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java
index 32debe3..82baf86 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java
index 4de23c1..e5bfca2 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnImportReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnInterfaceReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnInterfaceReference.java
index c4631e1..3f0b1a6 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnInterfaceReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnInterfaceReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
index ec23620..dda5b60 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
index 7625f7a..22fd7a2 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword1.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
index 032afbd..fbb03f7 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword2.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
index dfc3150..20a0716 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnKeyword3.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java
index 9df9d5f..e37c8e4 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnLocalName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java
index eb42584..a67e4ad 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMarkerAnnotationName.java
@@ -1,17 +1,19 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.codeassist.complete;
 
 import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 
@@ -21,6 +23,15 @@
 	}
 	
 	public TypeBinding resolveType(BlockScope scope) {
+		if(type instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) type;
+			Binding binding = scope.parent.getTypeOrPackage(qualifiedTypeReference.tokens); // step up from the ClassScope
+			if (!binding.isValidBinding()) {
+				scope.problemReporter().invalidType(this, (TypeBinding) binding);
+				throw new CompletionNodeFound();
+			}
+			throw new CompletionNodeFound(this, binding, scope);
+		}
 		throw new CompletionNodeFound(this, null, scope);
 	}
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
index 954cf15..987e6b9 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberAccess.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberValueName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberValueName.java
new file mode 100644
index 0000000..2bec1c8
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMemberValueName.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
+
+/*
+ * Completion node build by the parser in any case it was intending to
+ * reduce annotation's attribute name containing the cursor.
+ * e.g.
+ *
+ *	@Annot(attri[cursor]
+ *	class X {
+ *  }
+ *
+ *	---> @Annot(<CompletionOnAttributeName:attri>)
+ *		 class X {
+ *       }
+ */
+public class CompletionOnMemberValueName extends MemberValuePair {
+	public CompletionOnMemberValueName(char[] token, int sourceStart, int sourceEnd) {
+		super(token, sourceStart, sourceEnd, null);
+	}
+	
+	public StringBuffer print(int indent, StringBuffer output) {
+		output.append("<CompleteOnAttributeName:"); //$NON-NLS-1$
+		output.append(name);
+		output.append('>');
+		return output;
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
index c52ca37..d40546b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMessageSend.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java
index 5c6b267..f891633 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java
index 3ddab4a..8b03000 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodReturnType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java
index 15ecbc2..37f1744 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnMethodTypeParameter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
index 63e0b2d..b658bbb 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java
index 09c798d..e93d6ca 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnParameterizedQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java
index 9c6cb99..975ecdc 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedAllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedClassReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedClassReference.java
index e5a1152..c526d1c 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedClassReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedClassReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedExceptionReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedExceptionReference.java
index d2a108c..c17b83a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedExceptionReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedExceptionReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedInterfaceReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedInterfaceReference.java
index 7dd5167..72d1f28 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedInterfaceReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedInterfaceReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java
index 12359d0..fa5efef 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -38,9 +38,11 @@
 
 public class CompletionOnQualifiedNameReference extends QualifiedNameReference {
 	public char[] completionIdentifier;
-public CompletionOnQualifiedNameReference(char[][] previousIdentifiers, char[] completionIdentifier, long[] positions) {
+	public boolean isInsideAnnotationAttribute;
+public CompletionOnQualifiedNameReference(char[][] previousIdentifiers, char[] completionIdentifier, long[] positions, boolean isInsideAnnotationAttribute) {
 	super(previousIdentifiers, positions, (int) (positions[0] >>> 32), (int) positions[positions.length - 1]);
 	this.completionIdentifier = completionIdentifier;
+	this.isInsideAnnotationAttribute = isInsideAnnotationAttribute;
 }
 public StringBuffer printExpression(int indent, StringBuffer output) {
 
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java
index 5ebb6bc..cf2de0a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java
index 5d87886..d69aac2 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -38,15 +38,17 @@
 
 	public char[][] possibleKeywords;
 	public boolean canBeExplicitConstructor;
+	public boolean isInsideAnnotationAttribute;
 
-	public CompletionOnSingleNameReference(char[] source, long pos) {
-		this(source, pos, null, false);
+	public CompletionOnSingleNameReference(char[] source, long pos, boolean isInsideAnnotationAttribute) {
+		this(source, pos, null, false, isInsideAnnotationAttribute);
 	}
 
-	public CompletionOnSingleNameReference(char[] source, long pos, char[][] possibleKeywords, boolean canBeExplicitConstructor) {
+	public CompletionOnSingleNameReference(char[] source, long pos, char[][] possibleKeywords, boolean canBeExplicitConstructor, boolean isInsideAnnotationAttribute) {
 		super(source, pos);
 		this.possibleKeywords = possibleKeywords;
 		this.canBeExplicitConstructor = canBeExplicitConstructor;
+		this.isInsideAnnotationAttribute = isInsideAnnotationAttribute;
 	}
 
 	public StringBuffer printExpression(int indent, StringBuffer output) {
@@ -56,6 +58,9 @@
 	}
 
 	public TypeBinding resolveType(BlockScope scope) {
+		if(scope instanceof MethodScope) {
+			throw new CompletionNodeFound(this, scope, ((MethodScope)scope).insideTypeAnnotation);
+		}
 		throw new CompletionNodeFound(this, scope);
 	}
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
index aadb11d..7d40ec9 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index b3d2efa..2038322 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -66,8 +66,11 @@
 	protected static final int K_PARAMETERIZED_METHOD_INVOCATION = COMPLETION_PARSER + 30;
 	protected static final int K_PARAMETERIZED_ALLOCATION = COMPLETION_PARSER + 31;
 	protected static final int K_PARAMETERIZED_CAST = COMPLETION_PARSER + 32;
-	
+	protected static final int K_BETWEEN_ANNOTATION_NAME_AND_RPAREN = COMPLETION_PARSER + 33;
 
+	public final static char[] FAKE_TYPE_NAME = new char[]{' '};
+	public final static char[] VALUE = new char[]{'v', 'a', 'l', 'u', 'e'};
+	
 	/* public fields */
 
 	public int cursorLocation;
@@ -97,6 +100,11 @@
 	
 	static final int QUESTION = 1;
 	static final int COLON = 2;
+	
+	// K_BETWEEN_ANNOTATION_NAME_AND_RPAREN arguments
+	static final int LPAREN_NOT_CONSUMED = 1;
+	static final int LPAREN_CONSUMED = 2;
+	
 
 	// the type of the current invocation (one of the invocation type constants)
 	int invocationType;
@@ -117,7 +125,7 @@
 	static final int NEXTTOKEN = 1;
 	static final int YES = 2;
 	
-	
+	boolean isAlreadyAttached;
 public CompletionParser(ProblemReporter problemReporter) {
 	super(problemReporter);
 	this.reportSyntaxErrorIsRequired = false;
@@ -126,7 +134,9 @@
 	return ((CompletionScanner)scanner).completionIdentifier;
 }
 protected void attachOrphanCompletionNode(){
-	if(assistNode == null) return;
+	if(assistNode == null || this.isAlreadyAttached) return;
+	
+	this.isAlreadyAttached = true;
 	
 	if (this.isOrphanCompletionNode) {
 		ASTNode orphan = this.assistNode;
@@ -188,9 +198,15 @@
 			}
 		}
 
+		if(orphan instanceof MemberValuePair) {
+			buildMoreAnnotationCompletionContext((MemberValuePair) orphan);
+			return;
+		}
+		
 		if(orphan instanceof Annotation) {
 				TypeDeclaration fakeType =
 					new CompletionOnAnnotationOfType(
+							FAKE_TYPE_NAME, 
 							this.compilationUnit.compilationResult(),
 							(Annotation)orphan);
 				currentElement.add(fakeType, 0);
@@ -214,6 +230,75 @@
 			return;
 		} 
 	}
+	
+	if (this.isInsideAnnotation()) {
+		// push top expression on ast stack if it contains the completion node
+		Expression expression;
+		if (this.expressionPtr > -1) {
+			expression = this.expressionStack[this.expressionPtr];
+			if(expression == assistNode) {
+				if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+					if (expression instanceof SingleNameReference) {
+						SingleNameReference nameReference = (SingleNameReference) expression;
+						CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(nameReference.token, nameReference.sourceStart, nameReference.sourceEnd);
+						
+						buildMoreAnnotationCompletionContext(memberValueName);
+						return;
+					} else if (expression instanceof QualifiedNameReference) {
+						MemberValuePair valuePair =
+							new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, expression);
+						buildMoreAnnotationCompletionContext(valuePair);
+					}
+				} else {
+					int index;
+					if((index = lastIndexOfElement(K_ATTRIBUTE_VALUE_DELIMITER)) != -1) {
+						int attributeIndentifierPtr = this.elementInfoStack[index];
+						int identLengthPtr = this.identifierLengthPtr;
+						int identPtr = this.identifierPtr;
+						while (attributeIndentifierPtr < identPtr) {
+							identPtr -= this.identifierLengthStack[identLengthPtr--];
+						}
+						
+						if(attributeIndentifierPtr != identPtr) return;
+						
+						this.identifierLengthPtr = identLengthPtr;
+						this.identifierPtr = identPtr;
+						
+						this.identifierLengthPtr--;
+						MemberValuePair memberValuePair = new MemberValuePair(
+								this.identifierStack[this.identifierPtr--],
+								expression.sourceStart,
+								expression.sourceEnd,
+								expression);
+						
+						buildMoreAnnotationCompletionContext(memberValuePair);
+						return;
+					}
+				}
+			} else {
+				CompletionNodeDetector detector =  new CompletionNodeDetector(this.assistNode, expression);
+				if(detector.containsCompletionNode()) {
+					MemberValuePair valuePair =
+						new MemberValuePair(VALUE, expression.sourceStart, expression.sourceEnd, expression);
+					buildMoreAnnotationCompletionContext(valuePair);
+				}
+			}
+		}
+		
+		if (this.astPtr > -1) {
+			ASTNode node = this.astStack[this.astPtr];
+			if(node instanceof MemberValuePair) {
+				MemberValuePair memberValuePair = (MemberValuePair) node;
+				CompletionNodeDetector detector =  new CompletionNodeDetector(this.assistNode, memberValuePair);
+				if(detector.containsCompletionNode()) {
+					buildMoreAnnotationCompletionContext(memberValuePair);
+					this.assistNodeParent = detector.getCompletionNodeParent();
+					return;
+				}
+			}
+		}
+	}
+	
 	if(this.currentElement instanceof RecoveredType || this.currentElement instanceof RecoveredMethod) {
 		if(this.currentElement instanceof RecoveredType) {
 			RecoveredType recoveredType = (RecoveredType)this.currentElement;
@@ -271,7 +356,7 @@
 	}
 	
 	// the following code applies only in methods, constructors or initializers
-	if ((!isInsideMethod() && !isInsideFieldInitialization())) { 
+	if ((!isInsideMethod() && !isInsideFieldInitialization() && !isInsideAttributeValue())) { 
 		return;
 	}
 	
@@ -329,6 +414,76 @@
 		}
 	}
 }
+private void buildMoreAnnotationCompletionContext(MemberValuePair memberValuePair) {
+	if(this.identifierPtr < 0 || this.identifierLengthPtr < 0 ) return;
+	
+	TypeReference typeReference = this.getAnnotationType();
+	
+	int nodesToRemove = this.astPtr > -1 && this.astStack[this.astPtr] == memberValuePair ? 1 : 0;
+
+	NormalAnnotation annotation;
+	if (memberValuePair instanceof CompletionOnMemberValueName) { 
+		MemberValuePair[] memberValuePairs = null;
+		int length;
+		if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > nodesToRemove) {
+			if (this.astStack[this.astPtr] instanceof MemberValuePair) {
+				System.arraycopy(
+					this.astStack, 
+					(this.astPtr -= length) + 1, 
+					memberValuePairs = new MemberValuePair[length - nodesToRemove], 
+					0, 
+					length - nodesToRemove); 
+			}
+		}
+		annotation =
+			new CompletionOnAnnotationMemberValuePair(
+					typeReference,
+					this.intStack[this.intPtr--],
+					memberValuePairs,
+					memberValuePair);
+		
+		this.assistNode = memberValuePair;
+		this.assistNodeParent = annotation;
+		
+		if (memberValuePair.sourceEnd >= this.lastCheckPoint) {
+			this.lastCheckPoint = memberValuePair.sourceEnd + 1;
+		}
+	} else {
+		MemberValuePair[] memberValuePairs = null;
+		int length = 0;
+		if (astLengthPtr > -1 && (length = this.astLengthStack[this.astLengthPtr--]) > nodesToRemove) {
+			if (this.astStack[this.astPtr] instanceof MemberValuePair) {
+				System.arraycopy(
+					this.astStack, 
+					(this.astPtr -= length) + 1, 
+					memberValuePairs = new MemberValuePair[length - nodesToRemove + 1], 
+					0, 
+					length - nodesToRemove); 
+			}
+			if(memberValuePairs != null) {
+				memberValuePairs[length - nodesToRemove] = memberValuePair;
+			} else {
+				memberValuePairs = new MemberValuePair[]{memberValuePair};
+			}
+		} else {
+			memberValuePairs = new MemberValuePair[]{memberValuePair};
+		}
+		
+		annotation =
+			new NormalAnnotation(
+					typeReference,
+					this.intStack[this.intPtr--]);
+		annotation.memberValuePairs = memberValuePairs;
+					
+	}
+	TypeDeclaration fakeType =
+		new CompletionOnAnnotationOfType(
+				FAKE_TYPE_NAME, 
+				this.compilationUnit.compilationResult(),
+				annotation);
+	
+	currentElement.add(fakeType, 0);
+}
 private void buildMoreCompletionContext(Expression expression) {
 	Statement statement = expression;
 	int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
@@ -462,25 +617,44 @@
 				}
 				break nextElement;
 			case K_BINARY_OPERATOR :
-				if(expressionPtr > 0) {
+				if(expressionPtr > -1) {
 					Expression operatorExpression = null;
-					switch (info) {
-						case AND_AND :
-							operatorExpression = new AND_AND_Expression(this.expressionStack[expressionPtr-1], expression, info);
-							break;
-						case OR_OR :
-							operatorExpression = new OR_OR_Expression(this.expressionStack[expressionPtr-1], expression, info);
-							break;
-						case EQUAL_EQUAL :
-						case NOT_EQUAL :
-							operatorExpression = new EqualExpression(this.expressionStack[expressionPtr-1], expression, info);
-							break;
-						case INSTANCEOF :
-							// should never occur
-							break;
-						default :
-							operatorExpression = new BinaryExpression(this.expressionStack[expressionPtr-1], expression, info);
-							break;
+					Expression left = null;
+					if(expressionPtr == 0) {
+						// it is  a ***_NotName rule
+						if(this.identifierPtr > -1) {
+							left = getUnspecifiedReferenceOptimized();
+						}
+					} else {
+						left = this.expressionStack[expressionPtr-1];
+						// is it a ***_NotName rule ?
+						if(this.identifierPtr > -1) {
+							int start = (int) (identifierPositionStack[this.identifierPtr] >>> 32);
+							if(left.sourceStart < start) {
+								left = getUnspecifiedReferenceOptimized();
+							}
+						}
+					}
+					
+					if(left != null) {
+						switch (info) {
+							case AND_AND :
+								operatorExpression = new AND_AND_Expression(left, expression, info);
+								break;
+							case OR_OR :
+								operatorExpression = new OR_OR_Expression(left, expression, info);
+								break;
+							case EQUAL_EQUAL :
+							case NOT_EQUAL :
+								operatorExpression = new EqualExpression(left, expression, info);
+								break;
+							case INSTANCEOF :
+								// should never occur
+								break;
+							default :
+								operatorExpression = new BinaryExpression(left, expression, info);
+								break;
+						}
 					}
 					if(operatorExpression != null) {
 						assistNodeParent = operatorExpression;
@@ -596,7 +770,33 @@
 				}
 				assistNodeParent = arrayReference;
 				break;
-				
+			case K_BETWEEN_CASE_AND_COLON :
+				if(this.expressionPtr > 0) {
+					SwitchStatement switchStatement = new SwitchStatement();
+					switchStatement.expression = this.expressionStack[this.expressionPtr - 1];
+					if(this.astLengthPtr > -1 && this.astPtr > -1) {
+						int length = this.astLengthStack[this.astLengthPtr];
+						int newAstPtr = this.astPtr - length;
+						ASTNode firstNode = this.astStack[newAstPtr + 1];
+						if(length != 0 && firstNode.sourceStart > switchStatement.expression.sourceEnd) {
+							switchStatement.statements = new Statement[length + 1];
+							System.arraycopy(
+								this.astStack, 
+								newAstPtr + 1, 
+								switchStatement.statements, 
+								0, 
+								length); 
+						}
+					}
+					CaseStatement caseStatement = new CaseStatement(expression, expression.sourceStart, expression.sourceEnd);
+					if(switchStatement.statements == null) {
+						switchStatement.statements = new Statement[]{caseStatement};
+					} else {
+						switchStatement.statements[switchStatement.statements.length - 1] = caseStatement;
+					}
+					assistNodeParent = switchStatement;
+				}
+				break;
 		}
 	}
 	if(assistNodeParent != null) {
@@ -1105,6 +1305,29 @@
 	}
 	return false;
 }
+private boolean checkMemberValueName() {
+	/* check if current awaiting identifier is the completion identifier */
+	if (this.indexOfAssistIdentifier() < 0) return false;
+
+	if (this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) != K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) return false;
+	
+	if(this.identifierPtr > -1 && this.identifierLengthPtr > -1 && this.identifierLengthStack[this.identifierLengthPtr] == 1) {
+		char[] simpleName = this.identifierStack[this.identifierPtr];
+		long position = this.identifierPositionStack[this.identifierPtr--];
+		this.identifierLengthPtr--;
+		int end = (int) position;
+		int start = (int) (position >>> 32);
+		
+
+		CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(simpleName,start, end);
+		this.assistNode = memberValueName;
+		this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+		this.isOrphanCompletionNode = true;
+		
+		return true;
+	}
+	return false;
+}
 /**
  * Checks if the completion is in the context of a type and on a type reference in this type.
  * Persists the identifier into a fake field return type
@@ -1157,14 +1380,16 @@
  */
 public void completionIdentifierCheck(){
 	//if (assistNode != null) return; 
-
+	
+	if (checkMemberValueName()) return;
 	if (checkKeyword()) return;
 	if (checkRecoveredType()) return;
 	if (checkRecoveredMethod()) return;
 
 	// if not in a method in non diet mode and if not inside a field initializer, only record references attached to types
 	if (!(isInsideMethod() && !this.diet)
-		&& !isIndirectlyInsideFieldInitialization()) return; 
+		&& !isIndirectlyInsideFieldInitialization()
+		&& !isInsideAttributeValue()) return; 
 
 	/*
 	 	In some cases, the completion identifier may not have yet been consumed,
@@ -1437,11 +1662,6 @@
 	popElement(K_SELECTOR_INVOCATION_TYPE);
 	super.consumeEnterAnonymousClassBody();
 }
-protected void consumeEnterAnonymousClassBodySimpleName() {
-	popElement(K_SELECTOR_QUALIFIER);
-	popElement(K_SELECTOR_INVOCATION_TYPE);
-	super.consumeEnterAnonymousClassBodySimpleName();
-}
 protected void consumeEnterVariable() {
 	identifierPtr--;
 	identifierLengthPtr--;
@@ -1589,7 +1809,7 @@
 		final int typeDimensions = firstDimensions + extendedDimensions;
 		TypeReference type = getTypeReference(typeDimensions);
 		if (isVarArgs) {
-			type = type.copyDims(typeDimensions + 1);
+			type = copyDims(type, typeDimensions + 1);
 			if (extendedDimensions == 0) {
 				type.sourceEnd = endOfEllipsis;
 			}
@@ -1923,6 +2143,7 @@
 	
 	if ((index = this.indexOfAssistIdentifier()) < 0) {
 		super.consumeAnnotationName();
+		this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_NOT_CONSUMED);
 		return;
 	} 
 	
@@ -1960,12 +2181,7 @@
 	}
 
 	markerAnnotation = new CompletionOnMarkerAnnotationName(typeReference, typeReference.sourceStart);
-	int sourceStart = this.intStack[this.intPtr--];
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
+	this.intPtr--;
 	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
 	pushOnExpressionStack(markerAnnotation);
 	
@@ -1975,6 +2191,48 @@
 	
 	this.lastCheckPoint = markerAnnotation.sourceEnd + 1;
 }
+protected void consumeMarkerAnnotation() {
+	this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+	super.consumeMarkerAnnotation();
+}
+protected void consumeMemberValuePair() {
+	/* check if current awaiting identifier is the completion identifier */
+	if (this.indexOfAssistIdentifier() < 0){
+		super.consumeMemberValuePair();
+		MemberValuePair memberValuePair = (MemberValuePair) this.astStack[this.astPtr];
+		if(this.assistNode != null && memberValuePair.value == this.assistNode) {
+			this.assistNodeParent = memberValuePair;
+		}
+		return;
+	}
+	
+	char[] simpleName = this.identifierStack[this.identifierPtr];
+	long position = this.identifierPositionStack[this.identifierPtr--];
+	this.identifierLengthPtr--;
+	int end = (int) position;
+	int start = (int) (position >>> 32);
+	
+	this.expressionPtr--;
+	this.expressionLengthPtr--;
+
+	CompletionOnMemberValueName memberValueName = new CompletionOnMemberValueName(simpleName,start, end);
+	this.pushOnAstStack(memberValueName);
+	this.assistNode = memberValueName;
+	this.lastCheckPoint = this.assistNode.sourceEnd + 1;
+	this.isOrphanCompletionNode = true;
+	
+	this.restartRecovery = true;
+}
+protected void consumeMemberValueAsName() {
+	if ((indexOfAssistIdentifier()) < 0) {
+		super.consumeMemberValueAsName();
+	} else {
+		super.consumeMemberValueAsName();
+		if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN) {
+			this.restartRecovery = true;
+		}
+	}
+}
 protected void consumeMethodBody() {
 	popElement(K_BLOCK_DELIMITER);
 	super.consumeMethodBody();
@@ -2003,6 +2261,10 @@
 		popElement(K_LOCAL_INITIALIZER_DELIMITER);
 	}
 }
+protected void consumeSingleMemberAnnotation() {
+	this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+	super.consumeSingleMemberAnnotation();
+}
 protected void consumeStatementSwitch() {
 	super.consumeStatementSwitch();
 	if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SWITCH_LABEL) {
@@ -2014,6 +2276,10 @@
 	super.consumeNestedMethod();
 	if(!(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BLOCK_DELIMITER)) pushOnElementStack(K_BLOCK_DELIMITER);
 }
+protected void consumeNormalAnnotation() {
+	this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+	super.consumeNormalAnnotation();
+}
 protected void consumePrimaryNoNewArrayName() {
 	// this is class literal access, so reset potential receiver
 	this.invocationType = NO_RECEIVER;
@@ -2043,7 +2309,7 @@
 	int previous = this.previousToken;
 	int prevIdentifierPtr = this.previousIdentifierPtr;
 	
-	if (isInsideMethod() || isInsideFieldInitialization()) {
+	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAnnotation()) {
 		switch(token) {
 			case TokenNameLPAREN:
 				popElement(K_BETWEEN_NEW_AND_LEFT_BRACKET);
@@ -2073,7 +2339,7 @@
 		}
 	}
 	super.consumeToken(token);
-
+	
 	// if in field initializer (directly or not), on the completion identifier and not in recovery mode yet
 	// then position end of file at cursor location (so that we have the same behavior as
 	// in method bodies)
@@ -2085,7 +2351,7 @@
 	}
 	
 	// if in a method or if in a field initializer 
-	if (isInsideMethod() || isInsideFieldInitialization()) {
+	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAttributeValue()) {
 		switch (token) {
 			case TokenNameDOT:
 				switch (previous) {
@@ -2149,8 +2415,15 @@
 				switch (previous) {
 					case TokenNameIdentifier: // eg. fred[(]) or foo.fred[(])
 						if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_SELECTOR) {
-							this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, this.invocationType);
-							this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+							if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER,1) == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN &&
+									topKnownElementInfo(COMPLETION_OR_ASSIST_PARSER,1) == LPAREN_NOT_CONSUMED) {
+								this.popElement(K_SELECTOR);
+								this.popElement(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN);
+								this.pushOnElementStack(K_BETWEEN_ANNOTATION_NAME_AND_RPAREN, LPAREN_CONSUMED);
+							} else {
+								this.pushOnElementStack(K_SELECTOR_INVOCATION_TYPE, this.invocationType);
+								this.pushOnElementStack(K_SELECTOR_QUALIFIER, this.qualifier);
+							}
 						}
 						this.qualifier = -1;
 						this.invocationType = NO_RECEIVER;
@@ -2568,7 +2841,8 @@
 	return new CompletionOnQualifiedNameReference(
 					previousIdentifiers, 
 					assistName, 
-					positions); 	
+					positions,
+					isInsideAttributeValue()); 	
 }
 public TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
 	switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
@@ -2626,7 +2900,7 @@
 public NameReference createSingleAssistNameReference(char[] assistName, long position) {
 	int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
 	if(!isInsideMethod()) {
-		return new CompletionOnSingleNameReference(assistName, position);
+		return new CompletionOnSingleNameReference(assistName, position, isInsideAttributeValue());
 	} else {
 		boolean canBeExplicitConstructorCall = false;
 		if(kind == K_BLOCK_DELIMITER
@@ -2701,7 +2975,7 @@
 			}
 			System.arraycopy(keywords, 0 , keywords = new char[count][], 0, count);
 			
-			return new CompletionOnSingleNameReference(assistName, position, keywords, canBeExplicitConstructorCall);
+			return new CompletionOnSingleNameReference(assistName, position, keywords, canBeExplicitConstructorCall, isInsideAttributeValue());
 		}
 	}
 }
@@ -2736,6 +3010,7 @@
 
 	super.flushAssistState();
 	this.isOrphanCompletionNode = false;
+	this.isAlreadyAttached = false;
 	assistNodeParent = null;
 	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
 	completionScanner.completedIdentifierStart = 0;
@@ -2822,6 +3097,15 @@
 		this.assistNode instanceof CompletionOnSingleNameReference &&
 		(((CompletionOnSingleNameReference)this.assistNode).token.length == 0);
 }
+protected boolean isInsideAnnotation() {
+	int i = elementPtr;
+	while(i > -1) {
+		if(elementKindStack[i] == K_BETWEEN_ANNOTATION_NAME_AND_RPAREN)
+			return true;
+		i--;
+	}
+	return false;
+}
 protected boolean isIndirectlyInsideBlock(){
 	int i = elementPtr;
 	while(i > -1) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
index 8b32d63..7523889 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -36,8 +36,10 @@
 	 */
 	public int completedIdentifierStart = 0;
 	public int completedIdentifierEnd = -1;
+	public int unicodeCharSize;
 
 	public static final char[] EmptyCompletionIdentifier = {};
+	
 public CompletionScanner(long sourceLevel) {
 	super(
 		false /*comment*/, 
@@ -67,10 +69,11 @@
 			this.completedIdentifierStart = this.startPosition;
 			this.completedIdentifierEnd = this.currentPosition - 1;
 			if (this.withoutUnicodePtr != 0){			// check unicode scenario
-				System.arraycopy(this.withoutUnicodeBuffer, 1, this.completionIdentifier = new char[this.withoutUnicodePtr], 0, this.withoutUnicodePtr);
+				int length = this.cursorLocation + 1 - this.startPosition - this.unicodeCharSize;
+				System.arraycopy(this.withoutUnicodeBuffer, 1, this.completionIdentifier = new char[length], 0, length);
 			} else {
-				int length = this.cursorLocation + 1 - this.startPosition;
 				// no char[] sharing around completionIdentifier, we want it to be unique so as to use identity checks	
+				int length = this.cursorLocation + 1 - this.startPosition;
 				System.arraycopy(this.source, this.startPosition, (this.completionIdentifier = new char[length]), 0, length);
 			}
 			return this.completionIdentifier;
@@ -78,84 +81,11 @@
 	}
 	return super.getCurrentIdentifierSource();
 }
-/* 
- * Identifier splitting for unicodes.
- * Only store the current unicode if we did not pass the cursor location.
- * Note: this does not handle cases where the cursor is in the middle of a unicode
- */
-public boolean getNextCharAsJavaIdentifierPart() {
 
-	if (this.currentPosition >= this.source.length) // handle the obvious case upfront
-		return false;
-
-	int temp = this.currentPosition;
-	try {
-		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			if (!Character.isJavaIdentifierPart(this.currentCharacter)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			if (temp < this.cursorLocation && this.cursorLocation < this.currentPosition-1){
-				throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_UNICODE);
-			}
-			// 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)){
-			    unicodeStoreAt(++this.withoutUnicodePtr);
-			}
-			return true;
-		} //-------------end unicode traitement--------------
-		else {
-			if (!Character.isJavaIdentifierPart(this.currentCharacter)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			if (this.withoutUnicodePtr != 0){
-				// 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)){
-				    unicodeStoreAt(++this.withoutUnicodePtr);
-				}
-			}
-			return true;
-		}
-	} catch (IndexOutOfBoundsException e) {
-		this.currentPosition = temp;
-		return false;
-	}
-}
 public int getNextToken() throws InvalidInputException {
 
 	this.wasAcr = false;
+	this.unicodeCharSize = 0;
 	if (this.diet) {
 		jumpOverMethodBody();
 		this.diet = false;
@@ -421,9 +351,22 @@
 						}
 						throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
 					}
-					if (getNextChar('\\'))
+					if (getNextChar('\\')) {
+						if (this.unicodeAsBackSlash) {
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} else {
+							this.currentCharacter = this.source[this.currentPosition++];
+						}
 						scanEscapeCharacter();
-					else { // consume next character
+					} else { // consume next character
 						this.unicodeAsBackSlash = false;
 						boolean checkIfUnicode = false;
 						try {
@@ -437,7 +380,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-							    this.unicodeStoreAt(++this.withoutUnicodePtr);
+							    this.unicodeStore();
 							}
 						}
 					}
@@ -466,7 +409,7 @@
 							isUnicode = true;
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-							    this.unicodeStoreAt(++this.withoutUnicodePtr);
+							    this.unicodeStore();
 							}
 						}
 
@@ -501,21 +444,25 @@
 								throw new InvalidInputException(INVALID_CHAR_IN_STRING);
 							}
 							if (this.currentCharacter == '\\') {
-								int escapeSize = this.currentPosition;
-								boolean backSlashAsUnicodeInString = this.unicodeAsBackSlash;
-								//scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
-								scanEscapeCharacter();
-								escapeSize = this.currentPosition - escapeSize;
-								if (this.withoutUnicodePtr == 0) {
-									//buffer all the entries that have been left aside....
-
-									unicodeInitializeBuffer(this.currentPosition - escapeSize - 1 - this.startPosition);
-									this.unicodeStoreAt(++this.withoutUnicodePtr);
-								} else { //overwrite the / in the buffer
-								    this.unicodeStoreAt(this.withoutUnicodePtr);
-									if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
+								if (this.unicodeAsBackSlash) {
+									this.withoutUnicodePtr--;
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
 										this.withoutUnicodePtr--;
 									}
+								} else {
+									if (this.withoutUnicodePtr == 0) {
+										unicodeInitializeBuffer(this.currentPosition - this.startPosition);
+									}
+									this.withoutUnicodePtr --;
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								// we need to compute the escape character in a separate buffer
+								scanEscapeCharacter();
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
 								}
 							}
 							// consume next character
@@ -525,7 +472,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-								    this.unicodeStoreAt(++this.withoutUnicodePtr);
+								    this.unicodeStore();
 								}
 							}
 
@@ -703,7 +650,7 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-									    this.unicodeStoreAt(++this.withoutUnicodePtr);
+									    this.unicodeStore();
 									}
 								}
 	
@@ -823,10 +770,18 @@
 	}
 	return TokenNameEOF;
 }
-/*
- * In case we actually read a keyword, but the cursor is located inside,
- * we pretend we read an identifier.
- */
+public final void getNextUnicodeChar() throws InvalidInputException {
+	int temp = this.currentPosition; // the \ is already read
+	super.getNextUnicodeChar();
+	this.unicodeCharSize += (this.currentPosition - temp);
+	if (temp < this.cursorLocation && this.cursorLocation < this.currentPosition-1){
+		throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_UNICODE);
+	}
+}
+///*
+// * In case we actually read a keyword, but the cursor is located inside,
+// * we pretend we read an identifier.
+// */
 public int scanIdentifierOrKeyword() {
 
 	int id = super.scanIdentifierOrKeyword();
@@ -839,6 +794,7 @@
 	}
 	return id;
 }
+
 public int scanNumber(boolean dotPrefix) throws InvalidInputException {
 	
 	int token = super.scanNumber(dotPrefix);
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java
index 9c88e97..e853d31 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/InvalidCursorLocation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
index 278a383..4771072 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistOptions.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -38,13 +38,17 @@
 		"org.eclipse.jdt.core.codeComplete.localSuffixes"; 	//$NON-NLS-1$
 	public static final String OPTION_ArgumentSuffixes =
 		"org.eclipse.jdt.core.codeComplete.argumentSuffixes"; 	//$NON-NLS-1$
-	public static final String OPTION_PerformRestrictionsCheck =
+	public static final String OPTION_PerformForbiddenReferenceCheck =
 		"org.eclipse.jdt.core.codeComplete.restrictionsCheck"; 	//$NON-NLS-1$
+	public static final String OPTION_PerformDiscouragedReferenceCheck =
+		"org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"; 	//$NON-NLS-1$
+	
 	public static final String ENABLED = "enabled"; //$NON-NLS-1$
 	public static final String DISABLED = "disabled"; //$NON-NLS-1$
 
 	public boolean checkVisibility = false;
-	public boolean checkRestrictions = false;
+	public boolean checkForbiddenReference = false;
+	public boolean checkDiscouragedReference = false;
 	public boolean forceImplicitQualification = false;
 	public char[][] fieldPrefixes = null;
 	public char[][] staticFieldPrefixes = null;
@@ -168,11 +172,18 @@
 				}
 			}
 		}
-		if ((optionValue = optionsMap.get(OPTION_PerformRestrictionsCheck)) != null) {
+		if ((optionValue = optionsMap.get(OPTION_PerformForbiddenReferenceCheck)) != null) {
 			if (ENABLED.equals(optionValue)) {
-				this.checkRestrictions = true;
+				this.checkForbiddenReference = true;
 			} else if (DISABLED.equals(optionValue)) {
-				this.checkRestrictions = false;
+				this.checkForbiddenReference = false;
+			}
+		}
+		if ((optionValue = optionsMap.get(OPTION_PerformDiscouragedReferenceCheck)) != null) {
+			if (ENABLED.equals(optionValue)) {
+				this.checkDiscouragedReference = true;
+			} else if (DISABLED.equals(optionValue)) {
+				this.checkDiscouragedReference = false;
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index 2de6406..eebf89a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -73,6 +73,7 @@
 	protected static final int K_TYPE_DELIMITER = ASSIST_PARSER + 2; // whether we are inside a type declaration
 	protected static final int K_METHOD_DELIMITER = ASSIST_PARSER + 3; // whether we are inside a method declaration
 	protected static final int K_FIELD_INITIALIZER_DELIMITER = ASSIST_PARSER + 4; // whether we are inside a field initializer
+	protected static final int K_ATTRIBUTE_VALUE_DELIMITER = ASSIST_PARSER + 5; // whether we are inside a annotation attribute valuer
 	
 	// selector constants
 	protected static final int THIS_CONSTRUCTOR = -1;
@@ -274,15 +275,18 @@
 	popElement(K_SELECTOR);
 	pushOnElementStack(K_TYPE_DELIMITER);
 }
-protected void consumeEnterAnonymousClassBodySimpleName() {
-	super.consumeEnterAnonymousClassBodySimpleName();
-	popElement(K_SELECTOR);
-	pushOnElementStack(K_TYPE_DELIMITER);
+protected void consumeEnterMemberValue() {
+	super.consumeEnterMemberValue();
+	pushOnElementStack(K_ATTRIBUTE_VALUE_DELIMITER, this.identifierPtr);
 }
 protected void consumeEnumHeader() {
 	super.consumeEnumHeader();
 	pushOnElementStack(K_TYPE_DELIMITER);
 }
+protected void consumeExitMemberValue() {
+	super.consumeExitMemberValue();
+	popElement(K_ATTRIBUTE_VALUE_DELIMITER);
+}
 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
 	super.consumeExplicitConstructorInvocation(flag, recFlag);
 	popElement(K_SELECTOR);
@@ -299,6 +303,24 @@
 	super.consumeInterfaceHeader();
 	pushOnElementStack(K_TYPE_DELIMITER);
 }
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.compilationUnit.types = new TypeDeclaration[length];
+		this.astPtr -= length;
+		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+	}
+}
 protected void consumeMethodBody() {
 	super.consumeMethodBody();
 	popElement(K_METHOD_DELIMITER);
@@ -658,7 +680,7 @@
 	}
 	// register message send selector only if inside a method or if looking at a field initializer 
 	// and if the current token is an open parenthesis
-	if (isInsideMethod() || isInsideFieldInitialization()) {
+	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAttributeValue()) {
 		switch (token) {
 			case TokenNameLPAREN :
 				switch (this.previousToken) {
@@ -1058,6 +1080,19 @@
 	}
 	return false;
 }
+protected boolean isInsideAttributeValue(){
+	int i = elementPtr;
+	while(i > -1) {
+		switch (elementKindStack[i]) {
+			case K_TYPE_DELIMITER : return false;
+			case K_METHOD_DELIMITER : return false;
+			case K_FIELD_INITIALIZER_DELIMITER : return false;
+			case K_ATTRIBUTE_VALUE_DELIMITER : return true;
+		}
+		i--;
+	}
+	return false;
+}
 protected boolean isInsideFieldInitialization(){
 	int i = elementPtr;
 	while(i > -1) {
@@ -1338,6 +1373,12 @@
 	realBlockStack[realBlockPtr = 0] = 0;
 	
 	popUntilElement(K_TYPE_DELIMITER);
+
+	if(this.topKnownElementKind(ASSIST_PARSER) != K_TYPE_DELIMITER) {
+		// is outside a type and inside a compilation unit.
+		// remove all elements.
+		this.flushElementStack();
+	}
 }
 protected void pushOnElementStack(int kind){
 	this.pushOnElementStack(kind, 0);
@@ -1392,7 +1433,7 @@
 			break;
 		case TokenNameRBRACE :
 			super.recoveryTokenCheck();
-			if(currentElement != oldElement) {
+			if(currentElement != oldElement && !isInsideAttributeValue()) {
 				if(oldElement instanceof RecoveredInitializer
 					|| oldElement instanceof RecoveredMethod
 					|| (oldElement instanceof RecoveredBlock && oldElement.parent instanceof RecoveredInitializer)) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
index 55cf2a7..1cf0837 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Engine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java
index 571f0c2..71074d3 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/Keywords.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
new file mode 100644
index 0000000..1054de3
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadoc.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.*;
+
+/**
+ * Node representing a Javadoc comment including code selection.
+ */
+public class SelectionJavadoc extends Javadoc {
+
+	Expression selectedNode;
+
+	public SelectionJavadoc(int sourceStart, int sourceEnd) {
+		super(sourceStart, sourceEnd);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Javadoc#print(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer print(int indent, StringBuffer output) {
+		super.print(indent, output);
+		if (this.selectedNode != null) {
+			String selectedString = null;
+			if (this.selectedNode instanceof JavadocFieldReference) {
+				JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
+				if (fieldRef.methodBinding != null) {
+					selectedString = "<SelectOnMethod:"; //$NON-NLS-1$
+				} else {
+					selectedString = "<SelectOnField:"; //$NON-NLS-1$
+				}
+			} else if (this.selectedNode instanceof JavadocMessageSend) {
+				selectedString = "<SelectOnMethod:"; //$NON-NLS-1$
+			} else if (this.selectedNode instanceof JavadocAllocationExpression) {
+				selectedString = "<SelectOnConstructor:"; //$NON-NLS-1$
+			} else if (this.selectedNode instanceof JavadocSingleNameReference) {
+				selectedString = "<SelectOnLocalVariable:"; //$NON-NLS-1$
+			} else if (this.selectedNode instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					selectedString = "<SelectOnType:"; //$NON-NLS-1$
+				}
+			} else if (this.selectedNode instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					selectedString = "<SelectOnType:"; //$NON-NLS-1$
+				}
+			} else {
+				selectedString = "<SelectOnType:"; //$NON-NLS-1$
+			}
+			int pos = output.length()-3;
+			output.replace(pos-2,pos, selectedString+selectedNode+'>');
+		}
+		return output;
+	}
+
+	/**
+	 * Resolve selected node if not null and throw exception to let clients know
+	 * that it has been found.
+	 * 
+	 * @throws SelectionNodeFound
+	 */
+	public void resolve(ClassScope scope) {
+		if (this.selectedNode != null) {
+			this.selectedNode.resolveType(scope);
+			Binding binding = null;
+			if (this.selectedNode instanceof JavadocFieldReference) {
+				JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
+				binding = fieldRef.binding;
+				if (binding == null && fieldRef.methodBinding != null) {
+					binding = fieldRef.methodBinding;
+				}
+			} else if (this.selectedNode instanceof JavadocMessageSend) {
+				binding = ((JavadocMessageSend) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocAllocationExpression) {
+				binding = ((JavadocAllocationExpression) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocSingleNameReference) {
+				binding = ((JavadocSingleNameReference) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					binding = typeRef.resolvedType;
+				}
+			} else if (this.selectedNode instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					binding = typeRef.resolvedType;
+				}
+			} else {
+				binding = this.selectedNode.resolvedType;
+			}
+			throw new SelectionNodeFound(binding);
+		}
+	}
+
+	/**
+	 * Resolve selected node if not null and throw exception to let clients know
+	 * that it has been found.
+	 * 
+	 * @throws SelectionNodeFound
+	 */
+	public void resolve(MethodScope scope) {
+		if (this.selectedNode != null) {
+			this.selectedNode.resolveType(scope);
+			Binding binding = null;
+			if (this.selectedNode instanceof JavadocFieldReference) {
+				JavadocFieldReference fieldRef = (JavadocFieldReference) this.selectedNode;
+				binding = fieldRef.binding;
+				if (binding == null && fieldRef.methodBinding != null) {
+					binding = fieldRef.methodBinding;
+				}
+			} else if (this.selectedNode instanceof JavadocMessageSend) {
+				binding = ((JavadocMessageSend) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocAllocationExpression) {
+				binding = ((JavadocAllocationExpression) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocSingleNameReference) {
+				binding = ((JavadocSingleNameReference) this.selectedNode).binding;
+			} else if (this.selectedNode instanceof JavadocSingleTypeReference) {
+				JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					binding = typeRef.resolvedType;
+				}
+			} else if (this.selectedNode instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) this.selectedNode;
+				if (typeRef.packageBinding == null) {
+					binding = typeRef.resolvedType;
+				}
+			} else {
+				binding = this.selectedNode.resolvedType;
+			}
+			throw new SelectionNodeFound(binding);
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java
new file mode 100644
index 0000000..cca0de5
--- /dev/null
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionJavadocParser.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.select;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.codeassist.SelectionEngine;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
+
+/**
+ * Parser specialized for decoding javadoc comments which includes code selection.
+ */
+public class SelectionJavadocParser extends JavadocParser {
+	
+	int selectionStart;
+	int selectionEnd;
+	ASTNode selectedNode;
+
+	public SelectionJavadocParser(SelectionParser sourceParser) {
+		super(sourceParser);
+		this.kind = SELECTION_PARSER;
+	}
+
+	/*
+	 * Do not parse comment if selection is not included.
+	 */
+	public boolean checkDeprecation(int commentPtr) {
+		this.selectionStart = ((SelectionParser)sourceParser).selectionStart;
+		this.selectionEnd = ((SelectionParser)sourceParser).selectionEnd;
+		this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
+		this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr];
+		if (this.javadocStart <= this.selectionStart && this.selectionEnd <= this.javadocEnd) {
+			if (SelectionEngine.DEBUG) {
+				System.out.println("SELECTION in Javadoc:"); //$NON-NLS-1$
+			}
+			super.checkDeprecation(commentPtr);
+		} else {
+			this.docComment = null;
+		}
+		return false;
+	}
+
+	/*
+	 * Replace stored Javadoc node with specific selection one.
+	 */
+	protected boolean commentParse() {
+		this.docComment = new SelectionJavadoc(this.javadocStart, this.javadocEnd);
+		return super.commentParse();
+	}
+
+	/*
+	 * Create argument expression and store it if it includes selection.
+	 */
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+		// Create argument as we may need it after
+		Expression expression = (Expression) super.createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+		// See if selection is in argument
+		int start = ((TypeReference)typeRef).sourceStart;
+		int end = ((TypeReference)typeRef).sourceEnd;
+		if (start <= this.selectionStart && this.selectionEnd <= end) {
+			selectedNode = expression;
+			this.abort = true;
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected argument="+selectedNode); //$NON-NLS-1$
+			}
+		}
+		return expression;
+	}
+
+	/*
+	 * Verify if field identifier positions include selection.
+	 * If so, create field reference, store it and abort comment parse.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createFieldReference(Object receiver) throws InvalidInputException {
+		int start = (int) (this.identifierPositionStack[0] >>> 32);
+		int end = (int) this.identifierPositionStack[0];
+		if (start <= this.selectionStart && this.selectionEnd <= end) {
+			selectedNode = (ASTNode) super.createFieldReference(receiver);
+			this.abort = true;
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected field="+selectedNode); //$NON-NLS-1$
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Verify if method identifier positions include selection.
+	 * If so, create field reference, store it and abort comment parse.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
+		int start = (int) (this.identifierPositionStack[0] >>> 32);
+		int end = (int) this.identifierPositionStack[0];
+		if (start <= this.selectionStart && this.selectionEnd <= end) {
+			selectedNode = (ASTNode) super.createMethodReference(receiver, arguments);
+			this.abort = true;
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected method="+selectedNode); //$NON-NLS-1$
+			}
+		}
+		return null;
+	}
+
+	/*
+	 * Create type reference and verify if it includes selection.
+	 * If so, store it and abort comment parse.
+	 * Otherwise return null as we do not need this reference.
+	 */
+	protected Object createTypeReference(int primitiveToken) {
+		// Need to create type ref in case it was needed by members
+		TypeReference typeRef = (TypeReference) super.createTypeReference(primitiveToken);
+	
+		// See if node is concerned by selection
+		if (typeRef.sourceStart <= this.selectionStart && this.selectionEnd <= typeRef.sourceEnd) {
+			// See if selection is in one of tokens of qualification
+			if (typeRef instanceof JavadocQualifiedTypeReference) {
+				JavadocQualifiedTypeReference qualifiedTypeRef = (JavadocQualifiedTypeReference) typeRef;
+				int size = qualifiedTypeRef.tokens.length - 1;
+				for (int i=0; i<size; i++) {
+					int start = (int) (qualifiedTypeRef.sourcePositions[i] >>> 32);
+					int end = (int) qualifiedTypeRef.sourcePositions[i];
+					if (start <= this.selectionStart && this.selectionEnd <= end) {
+						int pos = i + 1;
+						char[][] tokens = new char[pos][];
+						System.arraycopy(this.identifierStack, this.identifierPtr+1, tokens, 0, pos);
+						long[] positions = new long[pos];
+						System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, pos);
+						selectedNode = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd);
+						this.abort = true; // we got selected node => cancel parse
+						if (SelectionEngine.DEBUG) {
+							System.out.println("	selected partial qualified type="+selectedNode); //$NON-NLS-1$
+						}
+						return typeRef;
+					}
+				}
+				// Selection is in last token => we'll store type ref as this
+			}
+			// Store type ref as selected node
+			selectedNode = typeRef;
+			this.abort = true; // we got selected node => cancel parse
+			if (SelectionEngine.DEBUG) {
+				System.out.println("	selected type="+selectedNode); //$NON-NLS-1$
+			}
+		}
+		return typeRef;
+	}
+
+	/*
+	 * Push param reference and verify if it includes selection.
+	 * If so, store it and abort comment parse.
+	 */
+	protected boolean pushParamName(boolean isTypeParam) {
+		if (super.pushParamName(isTypeParam)) {
+			Expression expression = (Expression) astStack[astPtr--];
+			// See if expression is concerned by selection
+			if (expression.sourceStart <= this.selectionStart && this.selectionEnd <= expression.sourceEnd) {
+				selectedNode = expression;
+				this.abort = true; // we got selected node => cancel parse
+				if (SelectionEngine.DEBUG) {
+					System.out.println("	selected param="+selectedNode); //$NON-NLS-1$
+				}
+			}
+		}
+		return false;
+	}
+
+	/*
+	 * Store selected node into doc comment.
+	 */
+	protected void updateDocComment() {
+		if (selectedNode instanceof Expression) {
+			((SelectionJavadoc) this.docComment).selectedNode = (Expression) selectedNode;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
index 5b9d33f..0fa124b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java
index 776cbcd..d990693 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnArgumentName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java
index b4c49f7..e62ad71 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnExplicitConstructorCall.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java
index cca165f..e544d1a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java
index bc233eb..d2cf2de 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnFieldType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java
index 07fdc2f..b5a5ca8 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnImportReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
index 9c66483..7bbb53a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnLocalName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
index f78846b..cd2ad3b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnMessageSend.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java
index ec3ecd9..adfb7e8 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnNameOfMemberValuePair.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
index 2b8a57e..a9de37d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
index 05d7095..2818d6d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java
index e23ef75..0752c6f 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnParameterizedSingleTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java
index 6acaf09..9b10e24 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedAllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java
index 33d8682..e1e0ac4 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java
index 7f09d6b..94441fe 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedSuperReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java
index d1d4137..683c16f 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java
index 2b92677..1f936a9 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -43,6 +43,12 @@
 	super(source, pos);
 }
 public TypeBinding resolveType(BlockScope scope) {
+	if (this.actualReceiverType != null) {
+		this.binding = scope.getField(this.actualReceiverType, token, this);
+		if (this.binding != null && this.binding.isValidBinding()) {
+			throw new SelectionNodeFound(binding);
+		}
+	} 
 	// it can be a package, type, member type, local variable or field
 	binding = scope.getBinding(token, Binding.VARIABLE | Binding.TYPE | Binding.PACKAGE, this, true /*resolve*/);
 	if (!binding.isValidBinding()) {
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java
index 236b2cd..839eaa6 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSingleTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java
index e7a718c..3ea538b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnSuperReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
index d80e28b..3597a0d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,7 +32,15 @@
 import org.eclipse.jdt.internal.compiler.problem.*;
 
 public class SelectionParser extends AssistParser {
+	// OWNER
+	protected static final int SELECTION_PARSER = 1024;
+	protected static final int SELECTION_OR_ASSIST_PARSER = ASSIST_PARSER + SELECTION_PARSER;
+	
+	// KIND : all values known by SelectionParser are between 1025 and 1549
+	protected static final int K_BETWEEN_CASE_AND_COLON = SELECTION_PARSER + 1; // whether we are inside a block
 
+	public ASTNode assistNodeParent; // the parent node of assist node
+	
 	/* public fields */
 
 	public int selectionStart, selectionEnd;
@@ -42,6 +50,8 @@
 	
 public SelectionParser(ProblemReporter problemReporter) {
 	super(problemReporter);
+	this.javadocParser = new SelectionJavadocParser(this);
+	this.javadocParser.checkDocComment = true;
 }
 public char[] assistIdentifier(){
 	return ((SelectionScanner)scanner).selectionIdentifier;
@@ -65,12 +75,58 @@
 			}
 		}
 		
-		Statement statement = (Statement)wrapWithExplicitConstructorCallIfNeeded(orphan);
-		currentElement = currentElement.add(statement, 0);
+		if (orphan instanceof Expression) {
+			buildMoreCompletionContext((Expression)orphan);
+		} else {
+			Statement statement = (Statement) orphan;
+			currentElement = currentElement.add(statement, 0);
+		}
 		currentToken = 0; // given we are not on an eof, we do not want side effects caused by looked-ahead token
 	}
 }
-
+private void buildMoreCompletionContext(Expression expression) {
+	ASTNode parentNode = null;
+	
+	int kind = topKnownElementKind(SELECTION_OR_ASSIST_PARSER);
+	if(kind != 0) {
+//		int info = topKnownElementInfo(SELECTION_OR_ASSIST_PARSER);
+		nextElement : switch (kind) {
+			case K_BETWEEN_CASE_AND_COLON :
+				if(this.expressionPtr > 0) {
+					SwitchStatement switchStatement = new SwitchStatement();
+					switchStatement.expression = this.expressionStack[this.expressionPtr - 1];
+					if(this.astLengthPtr > -1 && this.astPtr > -1) {
+						int length = this.astLengthStack[this.astLengthPtr];
+						int newAstPtr = this.astPtr - length;
+						ASTNode firstNode = this.astStack[newAstPtr + 1];
+						if(length != 0 && firstNode.sourceStart > switchStatement.expression.sourceEnd) {
+							switchStatement.statements = new Statement[length + 1];
+							System.arraycopy(
+								this.astStack, 
+								newAstPtr + 1, 
+								switchStatement.statements, 
+								0, 
+								length); 
+						}
+					}
+					CaseStatement caseStatement = new CaseStatement(expression, expression.sourceStart, expression.sourceEnd);
+					if(switchStatement.statements == null) {
+						switchStatement.statements = new Statement[]{caseStatement};
+					} else {
+						switchStatement.statements[switchStatement.statements.length - 1] = caseStatement;
+					}
+					parentNode = switchStatement;
+					this.assistNodeParent = parentNode;
+				}
+				break;
+		}
+	}
+	if(parentNode != null) {
+		currentElement = currentElement.add((Statement)parentNode, 0);
+	} else {
+		currentElement = currentElement.add((Statement)wrapWithExplicitConstructorCallIfNeeded(expression), 0);
+	}
+}
 private boolean checkRecoveredType() {
 	if (currentElement instanceof RecoveredType){
 		/* check if current awaiting identifier is the completion identifier */
@@ -353,66 +409,6 @@
 		lastIgnoredToken = -1;		
 	}
 }
-protected void consumeEnterAnonymousClassBodySimpleName() {
-	// EnterAnonymousClassBody ::= $empty
-
-	if (this.indexOfAssistIdentifier() < 0) {
-		super.consumeEnterAnonymousClassBodySimpleName();
-		return;
-	}
-	pushOnGenericsLengthStack(0);
-	pushOnGenericsIdentifiersLengthStack(identifierLengthStack[identifierLengthPtr]);
-	// trick to avoid creating a selection on type reference
-	char [] oldIdent = this.assistIdentifier();
-	this.setAssistIdentifier(null);		
-	TypeReference typeReference = getTypeReference(0);
-	this.setAssistIdentifier(oldIdent);	
-
-	TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult); 
-	anonymousType.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
-	anonymousType.bits |= ASTNode.AnonymousAndLocalMask;
-	QualifiedAllocationExpression alloc = new SelectionOnQualifiedAllocationExpression(anonymousType); 
-	markEnclosingMemberWithLocalType();
-	pushOnAstStack(anonymousType);
-
-	alloc.sourceEnd = rParenPos; //the position has been stored explicitly
-	int argumentLength;
-	if ((argumentLength = expressionLengthStack[expressionLengthPtr--]) != 0) {
-		expressionPtr -= argumentLength;
-		System.arraycopy(
-			expressionStack, 
-			expressionPtr + 1, 
-			alloc.arguments = new Expression[argumentLength], 
-			0, 
-			argumentLength); 
-	}
-	alloc.type = typeReference;
-
-	anonymousType.sourceEnd = alloc.sourceEnd;
-	//position at the type while it impacts the anonymous declaration
-	anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
-	alloc.sourceStart = intStack[intPtr--];
-	pushOnExpressionStack(alloc);
-
-	assistNode = alloc;
-	this.lastCheckPoint = alloc.sourceEnd + 1;
-	if (!diet){
-		this.restartRecovery	= true;	// force to restart in recovery mode
-		this.lastIgnoredToken = -1;
-		currentToken = 0; // opening brace already taken into account
-		hasReportedError = true;
-	}
-
-	anonymousType.bodyStart = scanner.currentPosition;
-	listLength = 0; // will be updated when reading super-interfaces
-	// recovery
-	if (currentElement != null){
-		lastCheckPoint = anonymousType.bodyStart;
-		currentElement = currentElement.add(anonymousType, 0);
-		currentToken = 0; // opening brace already taken into account
-		lastIgnoredToken = -1;		
-	}
-}
 protected void consumeEnterVariable() {
 	// EnterVariable ::= $empty
 	// do nothing by default
@@ -498,7 +494,7 @@
 		final int typeDimensions = firstDimensions + extendedDimensions;
 		TypeReference type = getTypeReference(typeDimensions);
 		if (isVarArgs) {
-			type = type.copyDims(typeDimensions + 1);
+			type = copyDims(type, typeDimensions + 1);
 			if (extendedDimensions == 0) {
 				type.sourceEnd = endOfEllipsis;
 			}
@@ -606,12 +602,6 @@
 	this.lastCheckPoint = typeReference.sourceEnd + 1;
 
 	markerAnnotation = new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]);
-	int sourceStart = markerAnnotation.sourceStart;
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
 	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
 	pushOnExpressionStack(markerAnnotation);
 }
@@ -787,12 +777,6 @@
 			0, 
 			length); 
 	}
-	int sourceStart = normalAnnotation.sourceStart;
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
 	normalAnnotation.declarationSourceEnd = this.rParenPos;
 	pushOnExpressionStack(normalAnnotation);
 }
@@ -842,12 +826,6 @@
 	singleMemberAnnotation = new SingleMemberAnnotation(typeReference, this.intStack[this.intPtr--]);
 	singleMemberAnnotation.memberValue = this.expressionStack[this.expressionPtr--];
 	this.expressionLengthPtr--;
-	int sourceStart = singleMemberAnnotation.sourceStart;
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
 	singleMemberAnnotation.declarationSourceEnd = this.rParenPos;
 	pushOnExpressionStack(singleMemberAnnotation);
 }
@@ -903,6 +881,23 @@
 		restartRecovery = true; // used to avoid branching back into the regular automaton		
 	}
 }
+protected void consumeToken(int token) {
+	super.consumeToken(token);
+	
+	// if in a method or if in a field initializer 
+	if (isInsideMethod() || isInsideFieldInitialization()) {
+		switch (token) {
+			case TokenNamecase :
+				pushOnElementStack(K_BETWEEN_CASE_AND_COLON);
+				break;
+			case TokenNameCOLON:
+				if(topKnownElementKind(SELECTION_OR_ASSIST_PARSER) == K_BETWEEN_CASE_AND_COLON) { 
+					popElement(K_BETWEEN_CASE_AND_COLON);
+				}
+				break;
+		}
+	}
+}
 protected void consumeTypeImportOnDemandDeclarationName() {
 	// TypeImportOnDemandDeclarationName ::= 'import' Name '.' '*'
 	/* push an ImportRef build from the last name 
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java
index 5ce63e2..d4f3981 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionScanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
index b21cdf4..6f0b3ac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -900,6 +900,7 @@
 	 * @param array the array in which the search is done
 	 * @return true if the array contains an occurrence of one of the characters, false otherwise.
 	 * @throws NullPointerException if array is null.
+	 * @since 3.1
 	 */
 	public static final boolean contains(char[] characters, char[] array) {
 		for (int i = array.length; --i >= 0;)
@@ -2225,6 +2226,35 @@
 	}
 
 	/**
+	 * Replace all occurrence of characters to be replaced with the remplacement character in the
+	 * given array.
+	 * <br>
+	 * <br>
+	 * For example:
+	 * <ol>
+	 * <li><pre>
+	 *    array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
+	 *    toBeReplaced = { 'b', 'c' }
+	 *    replacementChar = 'a'
+	 *    result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
+	 * </pre>
+	 * </li>
+	 * </ol>
+	 * 
+	 * @param array the given array
+	 * @param toBeReplaced characters to be replaced
+	 * @param replacementChar the replacement character
+	 * @throws NullPointerException if arrays are null.
+	 * @since 3.1
+	 */
+	public static final void replace(char[] array, char[] toBeReplaced, char replacementChar) {
+		for (int i = array.length; --i >= 0;)
+			for (int j = toBeReplaced.length; --j >= 0;)
+				if (array[i] == toBeReplaced[j])
+					array[i] = replacementChar;
+	}
+
+	/**
 	 * Answers a new array of characters with substitutions. No side-effect is operated on the original
 	 * array, in case no substitution happened, then the result is the same as the
 	 * original one.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 9092b81..c12ee08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added the following constants
@@ -72,7 +72,7 @@
  *     IBM Corporation - added the following constants
  *								   IllegalUsageOfQualifiedTypeReference
  *								   InvalidDigit
- ****************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.core.compiler;
  
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
@@ -253,6 +253,12 @@
 	/** @since 2.1 */
 	int EnclosingInstanceInConstructorCall = Internal + 28;
 	int AnonymousClassCannotExtendFinalClass = TypeRelated + 29;
+	/** @since 3.1 */
+	int CannotDefineAnnotationInLocalType = Internal + 30;
+	/** @since 3.1 */
+	int CannotDefineEnumInLocalType = Internal + 31;
+	/** @since 3.1 */
+	int NonStaticContextForEnumMemberType = Internal + 32;
 
 	// variables
 	int UndefinedName = 50;
@@ -415,7 +421,8 @@
 	int SuperfluousSemicolon = Internal + 180;
 	/** @since 3.0 */
 	int UnnecessaryCast = Internal + TypeRelated + 181;
-	/** @since 3.0 */
+	/** @deprecated - no longer generated, simply treated as UnnecessaryCast
+	 *   @since 3.0 */
 	int UnnecessaryArgumentCast = Internal + TypeRelated + 182;
 	/** @since 3.0 */
 	int UnnecessaryInstanceof = Internal + TypeRelated + 183;	
@@ -512,8 +519,15 @@
 	int UnterminatedComment = Syntax + Internal + 260;
 	/** @since 3.1 */
 	int InvalidDigit = Syntax + Internal + 262;	
+	/** @since 3.1 */
+	int InvalidLowSurrogate = Syntax + Internal + 263;
+	int InvalidHighSurrogate = Syntax + Internal + 264;
+	
 
 	// type related problems
+	/** @since 3.1 */
+	int DiscouragedReference = TypeRelated + 280;
+
 	int InterfaceCannotHaveInitializers = TypeRelated + 300;
 	int DuplicateModifierForType = TypeRelated + 301;
 	int IllegalModifierForClass = TypeRelated + 302;
@@ -860,13 +874,13 @@
 	/** @since 3.1 */
 	int ReferenceToForwardTypeVariable = TypeRelated + 528;
     /** @since 3.1 */
-	int BoundsMustBeAnInterface = TypeRelated + 529;	
+	int BoundMustBeAnInterface = TypeRelated + 529;	
     /** @since 3.1 */
 	int UnsafeRawConstructorInvocation = TypeRelated + 530;
     /** @since 3.1 */
 	int UnsafeRawMethodInvocation = TypeRelated + 531;
     /** @since 3.1 */
-	int UnsafeRawConversion = TypeRelated + 532;
+	int UnsafeTypeConversion = TypeRelated + 532;
     /** @since 3.1 */
 	int InvalidTypeVariableExceptionType = TypeRelated + 533;
 	/** @since 3.1 */
@@ -933,7 +947,19 @@
 	int BoundHasConflictingArguments = TypeRelated + 564;	
     /** @since 3.1 */
 	int DuplicateParameterizedMethods = MethodRelated + 565;
-
+	/** @since 3.1 */
+	int IllegalQualifiedParameterizedTypeAllocation = TypeRelated + 566;
+	/** @since 3.1 */
+	int DuplicateBounds = TypeRelated + 567;
+	/** @since 3.1 */
+	int BoundCannotBeArray = TypeRelated + 568;
+    /** @since 3.1 */
+	int UnsafeRawGenericConstructorInvocation = TypeRelated + 569;
+    /** @since 3.1 */
+	int UnsafeRawGenericMethodInvocation = TypeRelated + 570;
+	/** @since 3.1 */
+	int TypeParameterHidingType = TypeRelated + 571;
+	
 	/**
 	 * Foreach
 	 */
@@ -1012,10 +1038,22 @@
 	/** @since 3.1 */
 	int DisallowedTargetForAnnotation = TypeRelated + 622;
 	/** @since 3.1 */
-	int MethodMustOverride = TypeRelated + 623;
+	int MethodMustOverride = MethodRelated + 623;
 	/** @since 3.1 */
 	int AnnotationTypeDeclarationCannotHaveConstructor = Syntax + Internal + 624;
-		
+	/** @since 3.1 */
+	int AnnotationValueMustBeAnnotation = Internal + 625;
+	/** @since 3.1 */
+	int AnnotationTypeUsedAsSuperInterface = TypeRelated + 626;
+	/** @since 3.1 */
+	int MissingOverrideAnnotation = MethodRelated + 627;
+	/** @since 3.1 */
+	int FieldMissingDeprecatedAnnotation = Internal + 628;
+	/** @since 3.1 */
+	int MethodMissingDeprecatedAnnotation = Internal + 629;
+	/** @since 3.1 */
+	int TypeMissingDeprecatedAnnotation = Internal + 630;
+	
 	/**
 	 * Corrupted binaries
 	 */
@@ -1051,7 +1089,13 @@
 	int CannotInvokeSuperConstructorInEnum = MethodRelated + 757;
 	/** @since 3.1 */
 	int EnumAbstractMethodMustBeImplemented = MethodRelated + 758;
-
+	/** @since 3.1 */
+	int EnumSwitchCannotTargetField = FieldRelated + 759;
+	/** @since 3.1 */
+	int IllegalModifierForEnumConstructor = MethodRelated + 760;
+	/** @since 3.1 */
+	int MissingEnumConstantCase = FieldRelated + 761;
+	
 	/**
 	 * Var args
 	 */
@@ -1061,4 +1105,30 @@
 	int MethodVarargsArgumentNeedCast = MethodRelated + 801;
 	/** @since 3.1 */
 	int ConstructorVarargsArgumentNeedCast = ConstructorRelated + 802;
-}
\ No newline at end of file
+	/** @since 3.1 */
+	int VarargsConflict = MethodRelated + 803;
+	
+	/**
+	 * Javadoc Generic
+	 */
+	/** @since 3.1 */
+	int JavadocGenericMethodTypeArgumentMismatch = Javadoc + Internal + 850;
+	/** @since 3.1 */
+	int JavadocNonGenericMethod = Javadoc + Internal + 851;
+	/** @since 3.1 */
+	int JavadocIncorrectArityForParameterizedMethod = Javadoc + Internal + 852;
+	/** @since 3.1 */
+	int JavadocParameterizedMethodArgumentTypeMismatch = Javadoc + Internal + 853;
+	/** @since 3.1 */
+	int JavadocTypeArgumentsForRawGenericMethod = Javadoc + Internal + 854;
+	/** @since 3.1 */
+	int JavadocGenericConstructorTypeArgumentMismatch = Javadoc + Internal + 855;
+	/** @since 3.1 */
+	int JavadocNonGenericConstructor = Javadoc + Internal + 856;
+	/** @since 3.1 */
+	int JavadocIncorrectArityForParameterizedConstructor = Javadoc + Internal + 857;
+	/** @since 3.1 */
+	int JavadocParameterizedConstructorArgumentTypeMismatch = Javadoc + Internal + 858;
+	/** @since 3.1 */
+	int JavadocTypeArgumentsForRawGenericConstructor = Javadoc + Internal + 859;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java
index 508f522..c626edd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
index 1a105fb..0e88530 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 661f07f..168b33d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,11 +20,10 @@
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
-import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.impl.StringConstant;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 
 /**
  * Represents a class file wrapper on bytes, it is aware of its actual
@@ -80,14 +79,14 @@
 		f = new File(outputPath);
 		if (f.exists()) {
 			if (!f.isDirectory()) {
-				System.out.println(Util.bind("output.isFile" , f.getAbsolutePath())); //$NON-NLS-1$
-				throw new IOException(Util.bind("output.isFileNotDirectory" )); //$NON-NLS-1$
+				System.out.println(Messages.bind(Messages.output_isFile, f.getAbsolutePath()));
+				throw new IOException(Messages.output_isFileNotDirectory);
 			}
 		} else {
 			// we have to create that directory
 			if (!f.mkdirs()) {
-				System.out.println(Util.bind("output.dirName" , f.getAbsolutePath())); //$NON-NLS-1$
-				throw new IOException(Util.bind("output.notValidAll" )); //$NON-NLS-1$
+				System.out.println(Messages.bind(Messages.output_dirName, f.getAbsolutePath()));
+				throw new IOException(Messages.output_notValidAll);
 			}
 		}
 		StringBuffer outDir = new StringBuffer(outputPath);
@@ -103,8 +102,8 @@
 			} else {
 				// Need to add the outDir
 				if (!f.mkdir()) {
-					System.out.println(Util.bind("output.fileName" , f.getName())); //$NON-NLS-1$
-					throw new IOException(Util.bind("output.notValid" )); //$NON-NLS-1$
+					System.out.println(Messages.bind(Messages.output_fileName, f.getName()));
+					throw new IOException(Messages.output_notValid);
 				}
 			}
 			token = tokenizer.nextToken();
@@ -387,7 +386,7 @@
 					| AccNative);
 					
 		// set the AccSuper flag (has to be done after clearing AccSynchronized - since same value)
-		if (aType.isClass()) {
+		if (!aType.isInterface()) { // class or enum
 			accessFlags |= AccSuper;
 		}
 		
@@ -572,7 +571,7 @@
 					accessFlags |= AccPrivate;
 				} else if (innerClass.isLocalType() && !innerClass.isMemberType()) {
 					accessFlags |= AccPrivate;
-				} else if (innerClass.isMemberType() && (innerClass.isInterface() || innerClass.isAnnotationType())) {
+				} else if (innerClass.isMemberType() && innerClass.isInterface()) {
 					accessFlags |= AccStatic; // implicitely static
 				}
 				contents[contentsOffset++] = (byte) (accessFlags >> 8);
@@ -624,17 +623,12 @@
 			contents[contentsOffset++] = (byte) enclosingTypeIndex;
 			byte methodIndexByte1 = 0;
 			byte methodIndexByte2 = 0;
-			if (this.referenceBinding.scope != null) {
-				MethodScope methodScope = this.referenceBinding.scope.methodScope();
-				if (methodScope != null) {
-					ReferenceContext referenceContext = methodScope.referenceContext;
-					if (referenceContext instanceof AbstractMethodDeclaration) {
-						AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) referenceContext;
-						MethodBinding methodBinding = methodDeclaration.binding;
-						int enclosingMethodIndex = constantPool.literalIndexForMethod(methodBinding.selector, methodBinding.signature());
-						methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
-						methodIndexByte2 = (byte) enclosingMethodIndex;
-					}
+			if (this.referenceBinding instanceof LocalTypeBinding) {
+				MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod;
+				if (methodBinding != null) {
+					int enclosingMethodIndex = constantPool.literalIndexForMethod(methodBinding.selector, methodBinding.signature());
+					methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
+					methodIndexByte2 = (byte) enclosingMethodIndex;
 				}
 			}
 			contents[contentsOffset++] = methodIndexByte1;
@@ -939,7 +933,7 @@
 		generateCodeAttributeHeader();
 		StringBuffer buffer = new StringBuffer(25);
 		buffer.append("\t"  + problem.getMessage() + "\n" ); //$NON-NLS-1$ //$NON-NLS-2$
-		buffer.insert(0, Util.bind("compilation.unresolvedProblem" )); //$NON-NLS-1$
+		buffer.insert(0, Messages.compilation_unresolvedProblem);
 		String problemString = buffer.toString();
 		
 		codeStream.init(this);
@@ -993,9 +987,9 @@
 				}
 			} // insert the top line afterwards, once knowing how many problems we have to consider
 			if (count > 1) {
-				buffer.insert(0, Util.bind("compilation.unresolvedProblems" )); //$NON-NLS-1$
+				buffer.insert(0, Messages.compilation_unresolvedProblems);
 			} else {
-				buffer.insert(0, Util.bind("compilation.unresolvedProblem" )); //$NON-NLS-1$
+				buffer.insert(0, Messages.compilation_unresolvedProblem);
 			}
 			problemString = buffer.toString();
 		}
@@ -1055,9 +1049,9 @@
 				}
 			} // insert the top line afterwards, once knowing how many problems we have to consider
 			if (count > 1) {
-				buffer.insert(0, Util.bind("compilation.unresolvedProblems" )); //$NON-NLS-1$
+				buffer.insert(0, Messages.compilation_unresolvedProblems);
 			} else {
-				buffer.insert(0, Util.bind("compilation.unresolvedProblem" )); //$NON-NLS-1$
+				buffer.insert(0, Messages.compilation_unresolvedProblem);
 			}
 			problemString = buffer.toString();
 		}
@@ -1145,9 +1139,9 @@
 				}
 			} // insert the top line afterwards, once knowing how many problems we have to consider
 			if (count > 1) {
-				buffer.insert(0, Util.bind("compilation.unresolvedProblems" )); //$NON-NLS-1$
+				buffer.insert(0, Messages.compilation_unresolvedProblems);
 			} else {
-				buffer.insert(0, Util.bind("compilation.unresolvedProblem" )); //$NON-NLS-1$
+				buffer.insert(0, Messages.compilation_unresolvedProblem);
 			}
 			problemString = buffer.toString();
 		}
@@ -1664,8 +1658,8 @@
 					if (startPC != endPC) { // only entries for non zero length
 						if (endPC == -1) {
 							localVariable.declaringScope.problemReporter().abortDueToInternalError(
-								Util.bind("abort.invalidAttribute" , new String(localVariable.name)), //$NON-NLS-1$
-								(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
+									Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)), 
+									(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
 						}
 						if (isParameterizedType) {
 							numberOfGenericEntries++;
@@ -1956,7 +1950,7 @@
 						if (startPC != endPC) { // only entries for non zero length
 							if (endPC == -1) {
 								localVariable.declaringScope.problemReporter().abortDueToInternalError(
-									Util.bind("abort.invalidAttribute" , new String(localVariable.name)), //$NON-NLS-1$
+									Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)), 
 									(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
 							}
 							if (localContentsOffset + 10 >= this.contents.length) {
@@ -2675,7 +2669,7 @@
 					if (startPC != endPC) { // only entries for non zero length
 						if (endPC == -1) {
 							localVariable.declaringScope.problemReporter().abortDueToInternalError(
-								Util.bind("abort.invalidAttribute" , new String(localVariable.name)), //$NON-NLS-1$
+								Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)), 
 								(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
 						}
 						if (localContentsOffset + 10 > this.contents.length) {
@@ -3612,7 +3606,7 @@
 		if (annotationBinding == null) {
 			return false;
 		}
-		long metaTagBits = annotationBinding.tagBits;
+		long metaTagBits = annotationBinding.getAnnotationTagBits();
 		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
 			return false; // by default the retention is CLASS
 			
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
index d6b7475..ed266fc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
index ba20e99..6d9a508 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -183,10 +183,7 @@
 	public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
 		if (options.verbose) {
 			System.out.println(
-				Util.bind(
-					"compilation.loadBinary" , //$NON-NLS-1$
-					new String[] {
-						new String(binaryType.getName())}));
+				Messages.bind(Messages.compilation_loadBinary, new String(binaryType.getName())));
 //			new Exception("TRACE BINARY").printStackTrace(System.out);
 //		    System.out.println();
 		}
@@ -205,12 +202,12 @@
 			if (options.verbose) {
 				String count = String.valueOf(totalUnits + 1);
 				System.out.println(
-					Util.bind(
-						"compilation.request" , //$NON-NLS-1$
+					Messages.bind(Messages.compilation_request,
 						new String[] {
 							count,
 							count,
-							new String(sourceUnit.getFileName())}));
+							new String(sourceUnit.getFileName())
+						}));
 			}
 			// diet parsing for large collection of unit
 			CompilationUnitDeclaration parsedUnit;
@@ -241,10 +238,7 @@
 	 */
 	public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding, AccessRestriction accessRestriction) {
 		problemReporter.abortDueToInternalError(
-			Util.bind(
-				"abort.againstSourceModel" , //$NON-NLS-1$
-				String.valueOf(sourceTypes[0].getName()),
-				String.valueOf(sourceTypes[0].getFileName())));
+			Messages.bind(Messages.abort_againstSourceModel, new String[] { String.valueOf(sourceTypes[0].getName()), String.valueOf(sourceTypes[0].getFileName()) })); 
 	}
 
 	protected void addCompilationUnit(
@@ -281,12 +275,12 @@
 			try {
 				if (options.verbose) {
 					System.out.println(
-						Util.bind(
-							"compilation.request" , //$NON-NLS-1$
-							new String[] {
-								String.valueOf(i + 1),
-								String.valueOf(maxUnits),
-								new String(sourceUnits[i].getFileName())}));
+						Messages.bind(Messages.compilation_request,
+						new String[] {
+							String.valueOf(i + 1),
+							String.valueOf(maxUnits),
+							new String(sourceUnits[i].getFileName())
+						}));
 				}
 				// diet parsing for large collection of units
 				if (totalUnits < parseThreshold) {
@@ -326,12 +320,12 @@
 				try {
 					if (options.verbose)
 						System.out.println(
-							Util.bind(
-								"compilation.process" , //$NON-NLS-1$
-								new String[] {
-									String.valueOf(i + 1),
-									String.valueOf(totalUnits),
-									new String(unitsToProcess[i].getFileName())}));
+							Messages.bind(Messages.compilation_process,
+							new String[] {
+								String.valueOf(i + 1),
+								String.valueOf(totalUnits),
+								new String(unitsToProcess[i].getFileName())
+							}));
 					process(unit, i);
 				} finally {
 					// cleanup compilation unit result
@@ -341,12 +335,12 @@
 				requestor.acceptResult(unit.compilationResult.tagAsAccepted());
 				if (options.verbose)
 					System.out.println(
-						Util.bind(
-							"compilation.done", //$NON-NLS-1$
-							new String[] {
-								String.valueOf(i + 1),
-								String.valueOf(totalUnits),
-								new String(unit.getFileName())}));
+						Messages.bind(Messages.compilation_done,
+						new String[] {
+							String.valueOf(i + 1),
+							String.valueOf(totalUnits),
+							new String(unit.getFileName())
+						}));
 			}
 		} catch (AbortCompilation e) {
 			this.handleInternalException(e, unit);
@@ -362,10 +356,10 @@
 		if (options.verbose) {
 			if (totalUnits > 1) {
 				System.out.println(
-					Util.bind("compilation.units" , String.valueOf(totalUnits))); //$NON-NLS-1$
+					Messages.bind(Messages.compilation_units, String.valueOf(totalUnits))); 
 			} else {
 				System.out.println(
-					Util.bind("compilation.unit" , String.valueOf(totalUnits))); //$NON-NLS-1$
+					Messages.bind(Messages.compilation_unit, String.valueOf(totalUnits))); 
 			}
 		}
 	}
@@ -394,7 +388,7 @@
 			StringBuffer buffer = stringWriter.getBuffer();
 
 			String[] pbArguments = new String[] {
-				Util.bind("compilation.internalError" ) //$NON-NLS-1$
+				Messages.compilation_internalError
 					+ "\n"  //$NON-NLS-1$
 					+ buffer.toString()};
 
@@ -468,7 +462,7 @@
 					if (distantProblem instanceof DefaultProblem) { // fixup filename TODO (philippe) should improve API to make this official
 						((DefaultProblem) distantProblem).setOriginatingFileName(result.getFileName());
 					}
-					result	.record(distantProblem, unit);
+					result.record(distantProblem, unit);
 				}
 			} else {
 				/* distant internal exception which could not be reported back there */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ConfigurableOption.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ConfigurableOption.java
index 13e2858..7db63e1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ConfigurableOption.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ConfigurableOption.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java
index 5036df6..9b76e8a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java
index 0d8d039..20f1d3b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java
index 31570e3..af0129f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java
index a585e9f..405b59b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java
index f5e8d1b..046e2cb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
index a8db03f..ced0e79 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -94,7 +94,7 @@
 				codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
 			}			
 			codeStream.generateImplicitConversion(implicitConversion);
-			codeStream.updateLastRecordedEndPC(codeStream.position);
+			codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
 			return;
 		}
@@ -138,17 +138,18 @@
 		if (valueRequired) {
 			if (leftIsConst && !leftIsTrue) {
 				codeStream.iconst_0();
-				codeStream.updateLastRecordedEndPC(codeStream.position);
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 			} else {
 				if (rightIsConst && !rightIsTrue) {
 					codeStream.iconst_0();
-					codeStream.updateLastRecordedEndPC(codeStream.position);
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 				} else {
 					codeStream.iconst_1();
 				}
 				if (falseLabel.hasForwardReferences()) {
 					if ((bits & ValueForReturnMASK) != 0) {
-						codeStream.ireturn();
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
 						falseLabel.place();
 						codeStream.iconst_0();
 					} else {
@@ -163,7 +164,7 @@
 				}
 			}
 			codeStream.generateImplicitConversion(implicitConversion);
-			codeStream.updateLastRecordedEndPC(codeStream.position);
+			codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 		} else {
 			falseLabel.place();
 		}
@@ -221,7 +222,7 @@
 							valueRequired && !rightIsConst);
 					if (valueRequired && rightIsConst && rightIsTrue) {
 						codeStream.goto_(trueLabel);
-						codeStream.updateLastRecordedEndPC(codeStream.position);
+						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 					}
 					internalFalseLabel.place();
 				}
@@ -232,7 +233,7 @@
 					// need value, e.g. if (a == 1 && ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a!=1
 					if (leftIsConst && !leftIsTrue) {
 						codeStream.goto_(falseLabel);
-						codeStream.updateLastRecordedEndPC(codeStream.position);
+						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 						break generateOperands; // no need to generate right operand
 					}
 					if (rightInitStateIndex != -1) {
@@ -243,7 +244,7 @@
 							valueRequired && !rightIsConst);
 					if (valueRequired && rightIsConst && !rightIsTrue) {
 						codeStream.goto_(falseLabel);
-						codeStream.updateLastRecordedEndPC(codeStream.position);
+						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 					}
 				} else {
 					// no implicit fall through TRUE/FALSE --> should never occur
@@ -266,4 +267,4 @@
 		}
 		visitor.endVisit(this, scope);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 073b101..1dcc37a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -30,7 +30,7 @@
 	public final static int Bit5 = 0x10; 						// value for return (expression) | has all method bodies (unit) | supertype ref (type ref)
 	public final static int Bit6 = 0x20; 						// depth (name ref, msg) | only value required (binary expression) | ignore need cast check (cast expression)
 	public final static int Bit7 = 0x40; 						// depth (name ref, msg) | operator (operator) | need runtime checkcast (cast expression)
-	public final static int Bit8 = 0x80; 						// depth (name ref, msg) | operator (operator) 
+	public final static int Bit8 = 0x80; 						// depth (name ref, msg) | operator (operator) | unsafe cast (cast expression)
 	public final static int Bit9 = 0x100; 					// depth (name ref, msg) | operator (operator) | is local type (type decl)
 	public final static int Bit10= 0x200; 					// depth (name ref, msg) | operator (operator) | is anonymous type (type decl)
 	public final static int Bit11 = 0x400; 					// depth (name ref, msg) | operator (operator) | is member type (type decl)
@@ -94,9 +94,10 @@
 	public static final int OnlyValueRequiredMASK = Bit6; 
 
 	// for cast expressions
-	public static final int UnnecessaryCastMask = Bit15;
-	public static final int NeedRuntimeCheckCastMASK = Bit7;
+	public static final int UnnecessaryCastMASK = Bit15;
 	public static final int IgnoreNeedForCastCheckMASK = Bit6;
+	public static final int NeedRuntimeCheckCastMASK = Bit7;
+	public static final int UnsafeCastMask = Bit8;
 	
 	// for name references 
 	public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;	
@@ -160,64 +161,99 @@
 
 		super();
 	}
-	private static boolean checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType) {
+	private static boolean checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType, TypeBinding originalParameterType) {
 		argument.computeConversion(scope, parameterType, argumentType);
 
-		if (argumentType != NullBinding && parameterType.isWildcard() && ((WildcardBinding) parameterType).kind != Wildcard.SUPER)
-		    return true; // unsafeWildcardInvocation
-		if (argumentType != parameterType && argumentType.isRawType())
-	        if (parameterType.isBoundParameterizedType() || parameterType.isGenericType())
-				scope.problemReporter().unsafeRawConversion(argument, argumentType, parameterType);
+		if (argumentType != NullBinding && parameterType.isWildcard()) {
+			WildcardBinding wildcard = (WildcardBinding) parameterType;
+			if (wildcard.boundKind != Wildcard.SUPER && wildcard.otherBounds == null) // lub wildcards are tolerated
+		    	return true; // unsafeWildcardInvocation
+		}
+		TypeBinding checkedParameterType = originalParameterType == null ? parameterType : originalParameterType;
+		if (argumentType != checkedParameterType) {
+			if (argumentType.needsUncheckedConversion(checkedParameterType)) {
+				scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType);
+			}
+		}
 		return false;
 	}
 	public static void checkInvocationArguments(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding method, Expression[] arguments, TypeBinding[] argumentTypes, boolean argsContainCast, InvocationSite invocationSite) {
 		boolean unsafeWildcardInvocation = false;
 		TypeBinding[] params = method.parameters;
-		if (method.isVarargs()) {
-			// 4 possibilities exist for a call to the vararg method foo(int i, long ... value) : foo(1), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new long[] {1, 2})
-			int lastIndex = params.length - 1;
-			for (int i = 0; i < lastIndex; i++)
-			    if (checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i]))
-				    unsafeWildcardInvocation = true;
-		   int argLength = arguments.length;
-		   if (lastIndex < argLength) { // vararg argument was provided
-			   	TypeBinding parameterType = params[lastIndex];
-			    if (params.length != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions())
-			    	parameterType = ((ArrayBinding) parameterType).elementsType(); // single element was provided for vararg parameter
-				for (int i = lastIndex; i < argLength; i++)
-				    if (checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i]))
-					    unsafeWildcardInvocation = true;
-			}
-
-		   if (method.parameters.length == argumentTypes.length) { // 70056
-				int varargIndex = method.parameters.length - 1;
-				ArrayBinding varargType = (ArrayBinding) method.parameters[varargIndex];
-				TypeBinding lastArgType = argumentTypes[varargIndex];
-				if (lastArgType == NullBinding) {
-					if (!(varargType.leafComponentType().isBaseType() && varargType.dimensions() == 1))
-						scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
-				} else if (varargType.dimensions <= lastArgType.dimensions()) {
-					int dimensions = lastArgType.dimensions();
-					if (lastArgType.leafComponentType().isBaseType())
-						dimensions--;
-					if (varargType.dimensions < dimensions)
-						scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
-					else if (varargType.dimensions == dimensions && varargType.leafComponentType != lastArgType.leafComponentType())
-						scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+		int paramLength = params.length;
+		boolean isRawMemberInvocation = !method.isStatic() 
+				&& !receiverType.isUnboundWildcard() 
+				&& method.declaringClass.isRawType() 
+				&& (method.hasSubstitutedParameters() || method.hasSubstitutedReturnType());
+		
+		MethodBinding rawOriginalGenericMethod = null;
+		if (!isRawMemberInvocation) {
+			if (method instanceof ParameterizedGenericMethodBinding) {
+				ParameterizedGenericMethodBinding paramMethod = (ParameterizedGenericMethodBinding) method;
+				if (paramMethod.isUnchecked || (paramMethod.isRaw && (method.hasSubstitutedParameters() || method.hasSubstitutedReturnType()))) {
+					rawOriginalGenericMethod = method.original();
 				}
 			}
-		} else {
-			for (int i = 0, argLength = arguments.length; i < argLength; i++)
-			    if (checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i]))
-				    unsafeWildcardInvocation = true;
 		}
-		if (argsContainCast) {
-			CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
+		if (arguments != null) {
+			if (method.isVarargs()) {
+				// 4 possibilities exist for a call to the vararg method foo(int i, long ... value) : foo(1), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new long[] {1, 2})
+				int lastIndex = paramLength - 1;
+				for (int i = 0; i < lastIndex; i++) {
+					TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
+				    if (checkInvocationArgument(scope, arguments[i], params[i] , argumentTypes[i], originalRawParam)) {
+					    unsafeWildcardInvocation = true;
+				    }
+				}
+			   int argLength = arguments.length;
+			   if (lastIndex < argLength) { // vararg argument was provided
+				   	TypeBinding parameterType = params[lastIndex];
+					TypeBinding originalRawParam = null;
+	
+				    if (paramLength != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions()) {
+				    	parameterType = ((ArrayBinding) parameterType).elementsType(); // single element was provided for vararg parameter
+						originalRawParam = rawOriginalGenericMethod == null ? null : ((ArrayBinding)rawOriginalGenericMethod.parameters[lastIndex]).elementsType();
+				    }
+					for (int i = lastIndex; i < argLength; i++) {
+					    if (checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i], originalRawParam))
+						    unsafeWildcardInvocation = true;
+					}
+				}
+	
+			   if (paramLength == argumentTypes.length) { // 70056
+					int varargIndex = paramLength - 1;
+					ArrayBinding varargType = (ArrayBinding) params[varargIndex];
+					TypeBinding lastArgType = argumentTypes[varargIndex];
+					if (lastArgType == NullBinding) {
+						if (!(varargType.leafComponentType().isBaseType() && varargType.dimensions() == 1))
+							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+					} else if (varargType.dimensions <= lastArgType.dimensions()) {
+						int dimensions = lastArgType.dimensions();
+						if (lastArgType.leafComponentType().isBaseType())
+							dimensions--;
+						if (varargType.dimensions < dimensions)
+							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+						else if (varargType.dimensions == dimensions && varargType.leafComponentType != lastArgType.leafComponentType())
+							scope.problemReporter().varargsArgumentNeedCast(method, lastArgType, invocationSite);
+					}
+				}
+			} else {
+				for (int i = 0; i < paramLength; i++) {
+					TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
+				    if (checkInvocationArgument(scope, arguments[i], params[i], argumentTypes[i], originalRawParam))
+					    unsafeWildcardInvocation = true;
+				}
+			}
+			if (argsContainCast) {
+				CastExpression.checkNeedForArgumentCasts(scope, receiver, receiverType, method, arguments, argumentTypes, invocationSite);
+			}
 		}
 		if (unsafeWildcardInvocation) {
 		    scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
-		} else if (!receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
+		} else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && (method.hasSubstitutedParameters() || method.hasSubstitutedReturnType())) {
 		    scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
+		} else if (rawOriginalGenericMethod != null) {
+		    scope.problemReporter().unsafeRawGenericMethodInvocation((ASTNode)invocationSite, method);
 		}
 	}
 	public ASTNode concreteStatement() {
@@ -299,7 +335,7 @@
 		if (refType.hasRestrictedAccess()) {
 			AccessRestriction restriction = scope.environment().getAccessRestriction(type);
 			if (restriction != null) {
-				scope.problemReporter().forbiddenReference(type, this, restriction.getMessageTemplate());
+				scope.problemReporter().forbiddenReference(type, this, restriction.getMessageTemplate(), restriction.getProblemId());
 			}
 		}
 		if (!refType.isViewedAsDeprecated()) return false;
@@ -362,7 +398,9 @@
 		if (recipient != null) {
 			switch (recipient.kind()) {
 				case Binding.PACKAGE :
-					// TODO (philippe) need support for package annotations
+					PackageBinding packageBinding = (PackageBinding) recipient;
+					if ((packageBinding.tagBits & TagBits.AnnotationResolved) != 0) return;
+					packageBinding.tagBits |= TagBits.AnnotationResolved;
 					break;
 				case Binding.TYPE :
 				case Binding.GENERIC_TYPE :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 985a97d..ff98abc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -113,6 +113,7 @@
 					TypeReference thrownException = this.thrownExceptions[i];
 					ReferenceBinding thrownExceptionBinding = this.binding.thrownExceptions[bindingIndex];
 					char[][] bindingCompoundName = thrownExceptionBinding.compoundName;
+					if (bindingCompoundName == null) continue; // skip problem case
 					if (thrownException instanceof SingleTypeReference) {
 						// single type reference
 						int lengthName = bindingCompoundName.length;
@@ -318,6 +319,9 @@
 
 	public StringBuffer print(int tab, StringBuffer output) {
 
+		if (this.javadoc != null) {
+			this.javadoc.print(tab, output);
+		}
 		printIndent(tab, output);
 		printModifiers(this.modifiers, output);
 		if (this.annotations != null) printAnnotations(this.annotations, output);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java
index ec08039..3976972 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
index e631f12..a3e8027 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -238,6 +238,24 @@
 			this.resolvedType = scope.enclosingSourceType();
 		} else {
 			this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+			checkParameterizedAllocation: {
+				if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
+					ReferenceBinding currentType = (ReferenceBinding)this.resolvedType;
+					if (currentType == null) return null;
+					do {
+						// isStatic() is answering true for toplevel types
+						if ((currentType.modifiers & AccStatic) != 0) break checkParameterizedAllocation;
+						if (currentType.isRawType()) break checkParameterizedAllocation;
+					} while ((currentType = currentType.enclosingType())!= null);
+					ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
+					for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
+						if (qRef.typeArguments[i] != null) {
+							scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, this.resolvedType);
+							break;
+						}
+					}
+				}
+			}
 		}
 		// will check for null after args are resolved
 
@@ -294,8 +312,7 @@
 		}
 		if (isMethodUseDeprecated(binding, scope))
 			scope.problemReporter().deprecatedMethod(binding, this);
-		if (this.arguments != null)
-			checkInvocationArguments(scope, null, allocationType, this.binding, this.arguments, argumentTypes, argsContainCast, this);
+		checkInvocationArguments(scope, null, allocationType, this.binding, this.arguments, argumentTypes, argsContainCast, this);
 
 		return allocationType;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index df2b1d3..758660d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,11 +19,11 @@
  */
 public abstract class Annotation extends Expression {
 	
-	public TypeReference type;
+	final static MemberValuePair[] NoValuePairs = new MemberValuePair[0];
 	public int declarationSourceEnd;
 	public Binding recipient;
 	
-	final static MemberValuePair[] NoValuePairs = new MemberValuePair[0];
+	public TypeReference type;
 	
 	public static long getRetentionPolicy(char[] policyName) {
 		if (policyName == null || policyName.length == 0)
@@ -153,14 +153,14 @@
 		return tagBits;
 	}
 	
+	public abstract MemberValuePair[] memberValuePairs();
+	
 	public StringBuffer printExpression(int indent, StringBuffer output) {
 		output.append('@');
 		this.type.printExpression(0, output);
 		return output;
 	}
 	
-	public abstract MemberValuePair[] memberValuePairs();
-	
 	public TypeBinding resolveType(BlockScope scope) {
 		
 		this.constant = NotAConstant;
@@ -237,7 +237,7 @@
 				// tag bits onto recipient
 				switch (this.recipient.kind()) {
 					case Binding.PACKAGE :
-						// TODO (philippe) need support for package annotations
+						((PackageBinding)this.recipient).tagBits |= tagBits;
 						break;
 					case Binding.TYPE :
 					case Binding.GENERIC_TYPE :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
index c7ef29f..90d1323 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -113,28 +113,21 @@
 			// annotation methods can only return base types, String, Class, enum type, annotation types and arrays of these
 			checkAnnotationMethodType: {
 				TypeBinding leafReturnType = returnTypeBinding.leafComponentType();
-					
-				switch (leafReturnType.erasure().id) {
-					case T_byte :
-					case T_short :
-					case T_char :
-					case T_int :
-					case T_long :
-					case T_float :
-					case T_double :
-					case T_boolean :
-					case T_JavaLangString :
-					case T_JavaLangClass :
-						if (returnTypeBinding.dimensions() <= 1) // only 1-dimensional array permitted
+				if (returnTypeBinding.dimensions() <= 1) { // only 1-dimensional array permitted
+					switch (leafReturnType.erasure().id) {
+						case T_byte :
+						case T_short :
+						case T_char :
+						case T_int :
+						case T_long :
+						case T_float :
+						case T_double :
+						case T_boolean :
+						case T_JavaLangString :
+						case T_JavaLangClass :
 							break checkAnnotationMethodType;
-				}
-				if (leafReturnType.isEnum()) {
-					if (returnTypeBinding.dimensions() <= 1) // only 1-dimensional array permitted
-						break checkAnnotationMethodType;
-				}
-				if (leafReturnType.isAnnotationType()) {
-					scope.classScope().detectAnnotationCycle(scope.enclosingSourceType(), leafReturnType, this.returnType);
-					if (returnTypeBinding.dimensions() <= 1) // only 1-dimensional array permitted
+					}
+					if (leafReturnType.isEnum() || leafReturnType.isAnnotationType())
 						break checkAnnotationMethodType;
 				}
 				scope.problemReporter().invalidAnnotationMemberType(this);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
index 4a75e07..2f0e676 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -30,8 +30,6 @@
 
 	public void bind(MethodScope scope, TypeBinding typeBinding, boolean used) {
 
-		if (this.type != null)
-			this.type.resolvedType = typeBinding; // TODO (philippe) no longer necessary as when binding got resolved, it was recorded already (SourceTypeBinding#resolveTypesFor(MethodBinding))
 		// record the resolved type into the type reference
 		int modifierFlag = this.modifiers;
 
@@ -72,7 +70,7 @@
 	}
 
 	public boolean isVarArgs() {
-		return (this.type.bits & IsVarArgs) != 0;
+		return this.type != null &&  (this.type.bits & IsVarArgs) != 0;
 	}
 		
 	public StringBuffer print(int indent, StringBuffer output) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
index d1862ff..ac44817 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
index 9310cf7..9ac989a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -144,7 +144,7 @@
 		}
 			
 		if (expectedTb.isArrayType()) {
-			binding = (ArrayBinding) expectedTb;
+			this.resolvedType = this.binding = (ArrayBinding) expectedTb;
 			if (expressions == null)
 				return binding;
 			TypeBinding expectedElementsTb = binding.elementsType();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java
index 6c6d1ad..bf9c66a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
index fc0bb69..7307b3e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -62,11 +62,13 @@
 		Assignment assignment,
 		boolean valueRequired) {
 
+		int pc = codeStream.position;
 		receiver.generateCode(currentScope, codeStream, true);
 		if (receiver instanceof CastExpression	// ((type[])null)[0]
 				&& ((CastExpression)receiver).innermostCastedExpression().resolvedType == NullBinding){
 			codeStream.checkcast(receiver.resolvedType); 
 		}	
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
 		position.generateCode(currentScope, codeStream, true);
 		assignment.expression.generateCode(currentScope, codeStream, true);
 		codeStream.arrayAtPut(this.resolvedType.id, valueRequired);
@@ -194,7 +196,8 @@
 		if (arrayType != null) {
 			receiver.computeConversion(scope, arrayType, arrayType);
 			if (arrayType.isArrayType()) {
-				this.resolvedType = ((ArrayBinding) arrayType).elementsType();
+				TypeBinding elementType = ((ArrayBinding) arrayType).elementsType();
+				this.resolvedType = ((this.bits & IsStrictlyAssignedMASK) == 0) ? elementType.capture() : elementType;
 			} else {
 				scope.problemReporter().referenceMustBeArrayTypeAt(arrayType, this);
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
index 66d9947..b30a98c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index dedee1f..f3dba55 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
index e43c286..75ea4b2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Genady Beriozkin - added support for reporting assignment with no effect
@@ -75,13 +75,12 @@
 	void checkAssignment(BlockScope scope, TypeBinding lhsType, TypeBinding rhsType) {
 		
 		FieldBinding leftField = getLastField(this.lhs);
-		if (leftField != null &&  rhsType != NullBinding && lhsType.isWildcard() && ((WildcardBinding)lhsType).kind != Wildcard.SUPER) {
+		if (leftField != null &&  rhsType != NullBinding && lhsType.isWildcard() && ((WildcardBinding)lhsType).boundKind != Wildcard.SUPER) {
 		    scope.problemReporter().wildcardAssignment(lhsType, rhsType, this.expression);
-		} else if (leftField != null && leftField.declaringClass != null /*length pseudo field*/&& leftField.declaringClass.isRawType() 
-		        && (rhsType.isParameterizedType() || rhsType.isGenericType())) {
+		} else if (leftField != null && leftField.declaringClass != null /*length pseudo field*/&& leftField.declaringClass.isRawType()) {
 		    scope.problemReporter().unsafeRawFieldAssignment(leftField, rhsType, this.lhs);
 		} else if (rhsType.needsUncheckedConversion(lhsType)) {
-		    scope.problemReporter().unsafeRawConversion(this.expression, rhsType, lhsType);
+		    scope.problemReporter().unsafeTypeConversion(this.expression, rhsType, lhsType);
 		}		
 	}
 	
@@ -115,6 +114,8 @@
 			if (fieldRef.receiver.isThis() && !(fieldRef.receiver instanceof QualifiedThisReference)) {
 				return fieldRef.binding;
 			}			
+		} else if (someExpression instanceof PostfixExpression) { // recurse for postfix: i++ --> i
+			return getDirectBinding(((PostfixExpression) someExpression).lhs);
 		}
 		return null;
 	}
@@ -173,8 +174,10 @@
 			scope.problemReporter().expressionShouldBeAVariable(this.lhs);
 			return null;
 		}
-		TypeBinding lhsType = this.resolvedType = lhs.resolveType(scope);
+		TypeBinding lhsType = lhs.resolveType(scope);
 		expression.setExpectedType(lhsType); // needed in case of generic method invocation
+		if (lhsType != null) 
+			this.resolvedType = lhsType.capture();
 		TypeBinding rhsType = expression.resolveType(scope);
 		if (lhsType == null || rhsType == null) {
 			return null;
@@ -227,4 +230,4 @@
 		}
 		visitor.endVisit(this, scope);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
index d5a0b3e..cfb6a44 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -306,7 +306,8 @@
 							if (valueRequired) {
 								codeStream.iconst_1();
 								if ((bits & ValueForReturnMASK) != 0) {
-									codeStream.ireturn();
+									codeStream.generateImplicitConversion(this.implicitConversion);
+									codeStream.generateReturnBytecode(this);
 									falseLabel.place();
 									codeStream.iconst_0();
 								} else {
@@ -377,7 +378,8 @@
 							if (valueRequired) {
 								codeStream.iconst_1();
 								if ((bits & ValueForReturnMASK) != 0) {
-									codeStream.ireturn();
+									codeStream.generateImplicitConversion(this.implicitConversion);
+									codeStream.generateReturnBytecode(this);
 									falseLabel.place();
 									codeStream.iconst_0();
 								} else {
@@ -448,7 +450,8 @@
 							if (valueRequired) {
 								codeStream.iconst_1();
 								if ((bits & ValueForReturnMASK) != 0) {
-									codeStream.ireturn();
+									codeStream.generateImplicitConversion(this.implicitConversion);
+									codeStream.generateReturnBytecode(this);
 									falseLabel.place();
 									codeStream.iconst_0();
 								} else {
@@ -519,7 +522,8 @@
 				if (valueRequired) {
 					codeStream.iconst_1();
 					if ((bits & ValueForReturnMASK) != 0) {
-						codeStream.ireturn();
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
 						falseLabel.place();
 						codeStream.iconst_0();
 					} else {
@@ -541,7 +545,8 @@
 				if (valueRequired) {
 					codeStream.iconst_1();
 					if ((bits & ValueForReturnMASK) != 0) {
-						codeStream.ireturn();
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
 						falseLabel.place();
 						codeStream.iconst_0();
 					} else {
@@ -563,7 +568,8 @@
 				if (valueRequired) {
 					codeStream.iconst_1();
 					if ((bits & ValueForReturnMASK) != 0) {
-						codeStream.ireturn();
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
 						falseLabel.place();
 						codeStream.iconst_0();
 					} else {
@@ -585,7 +591,8 @@
 				if (valueRequired) {
 					codeStream.iconst_1();
 					if ((bits & ValueForReturnMASK) != 0) {
-						codeStream.ireturn();
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
 						falseLabel.place();
 						codeStream.iconst_0();
 					} else {
@@ -721,7 +728,7 @@
 					}
 				}
 				// reposition the endPC
-				codeStream.updateLastRecordedEndPC(codeStream.position);					
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				return;
 			}
 			// x > 0
@@ -743,7 +750,7 @@
 					}
 				}
 				// reposition the endPC
-				codeStream.updateLastRecordedEndPC(codeStream.position);					
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				return;
 			}
 		}
@@ -771,7 +778,7 @@
 							codeStream.ifgt(trueLabel);
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 					return;
 				}
 			} else {
@@ -794,7 +801,7 @@
 							codeStream.ifle(falseLabel);
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 					return;
 				} else {
 					// no implicit fall through TRUE/FALSE --> should never occur
@@ -835,7 +842,7 @@
 					}
 				}
 				// reposition the endPC
-				codeStream.updateLastRecordedEndPC(codeStream.position);					
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				return;
 			}
 			// x >= 0
@@ -857,7 +864,7 @@
 					}
 				}
 				// reposition the endPC
-				codeStream.updateLastRecordedEndPC(codeStream.position);					
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				return;
 			}
 		}
@@ -885,7 +892,7 @@
 							codeStream.ifge(trueLabel);
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 					return;
 				}
 			} else {
@@ -908,7 +915,7 @@
 							codeStream.iflt(falseLabel);
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 					return;
 				} else {
 					// no implicit fall through TRUE/FALSE --> should never occur
@@ -948,7 +955,7 @@
 						}
 					}
 				}
-				codeStream.updateLastRecordedEndPC(codeStream.position);
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 				return;
 			}
 			// x < 0
@@ -969,7 +976,7 @@
 						}
 					}
 				}
-				codeStream.updateLastRecordedEndPC(codeStream.position);
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 				return;
 			}
 		}
@@ -996,7 +1003,7 @@
 							codeStream.dcmpg();
 							codeStream.iflt(trueLabel);
 					}
-					codeStream.updateLastRecordedEndPC(codeStream.position);
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 					return;
 				}
 			} else {
@@ -1018,7 +1025,7 @@
 							codeStream.dcmpg();
 							codeStream.ifge(falseLabel);
 					}
-					codeStream.updateLastRecordedEndPC(codeStream.position);
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 					return;
 				} else {
 					// no implicit fall through TRUE/FALSE --> should never occur
@@ -1059,7 +1066,7 @@
 					}
 				}
 				// reposition the endPC
-				codeStream.updateLastRecordedEndPC(codeStream.position);					
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				return;
 			}
 			// x <= 0
@@ -1081,7 +1088,7 @@
 					}
 				}
 				// reposition the endPC
-				codeStream.updateLastRecordedEndPC(codeStream.position);					
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				return;
 			}
 		}
@@ -1109,7 +1116,7 @@
 							codeStream.ifle(trueLabel);
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 					return;
 				}
 			} else {
@@ -1132,7 +1139,7 @@
 							codeStream.ifgt(falseLabel);
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 					return;
 				} else {
 					// no implicit fall through TRUE/FALSE --> should never occur
@@ -1199,7 +1206,7 @@
 						}
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				}
 				return;
 			}
@@ -1249,7 +1256,7 @@
 						}
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				}
 				return;
 			}
@@ -1276,7 +1283,7 @@
 			}
 		}
 		// reposition the endPC
-		codeStream.updateLastRecordedEndPC(codeStream.position);					
+		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 	}
 	
 	/**
@@ -1318,7 +1325,7 @@
 						}
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				} else {
 					// <something equivalent to false> | x
 					left.generateOptimizedBoolean(
@@ -1367,7 +1374,7 @@
 						}
 					}
 					// reposition the endPC
-					codeStream.updateLastRecordedEndPC(codeStream.position);					
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 				} else {
 					// x | <something equivalent to false>
 					if ((bits & OnlyValueRequiredMASK) != 0) {
@@ -1412,7 +1419,7 @@
 			}
 		}
 		// reposition the endPC
-		codeStream.updateLastRecordedEndPC(codeStream.position);					
+		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 	}
 	
 	/**
@@ -1522,7 +1529,7 @@
 			}
 		}
 		// reposition the endPC
-		codeStream.updateLastRecordedEndPC(codeStream.position);					
+		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 	}
 	
 	public void generateOptimizedStringConcatenation(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
index f9170be..8695c16 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Block.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
index 2dede48..73afd3d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
index dab79fe..93accfc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
index ea3a9ae..70c6a99 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -84,7 +84,7 @@
 		TypeBinding switchExpressionType,
 		SwitchStatement switchStatement) {
 
-	    scope.switchCase = this; // record entering in a switch case block
+	    scope.enclosingCase = this; // record entering in a switch case block
 	    
 		if (constantExpression == null) {
 			// remember the default case into the associated switch statement
@@ -109,10 +109,14 @@
 				this.isEnumConstant = true;
 				if (constantExpression instanceof NameReference
 						&& (constantExpression.bits & RestrictiveFlagMASK) == Binding.FIELD) {
-					if (constantExpression instanceof QualifiedNameReference) {
-						 scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel((QualifiedNameReference)constantExpression);
+					NameReference reference = (NameReference) constantExpression;
+					FieldBinding field = reference.fieldBinding();
+					if ((field.modifiers & AccEnum) == 0) {
+						 scope.problemReporter().enumSwitchCannotTargetField(reference, field);
+					} else 	if (reference instanceof QualifiedNameReference) {
+						 scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field);
 					}
-					return Constant.fromValue(((NameReference)constantExpression).fieldBinding().id); // ordinal value
+					return Constant.fromValue(field.original().id); // ordinal value
 				}
 			} else {
 				return constantExpression.constant;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index bdf85b2..c179969 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
@@ -85,7 +85,7 @@
 	
 		// check need for left operand cast
 		int alternateLeftTypeId = expressionTypeId;
-		if ((expression.bits & UnnecessaryCastMask) == 0 && expression.resolvedType.isBaseType()) {
+		if ((expression.bits & UnnecessaryCastMASK) == 0 && expression.resolvedType.isBaseType()) {
 			// narrowing conversion on base type may change value, thus necessary
 			return;
 		} else  {
@@ -127,7 +127,7 @@
 			Expression argument = arguments[i];
 			if (argument instanceof CastExpression) {
  				// narrowing conversion on base type may change value, thus necessary
-				if ((argument.bits & UnnecessaryCastMask) == 0 && argument.resolvedType.isBaseType()) {
+				if ((argument.bits & UnnecessaryCastMASK) == 0 && argument.resolvedType.isBaseType()) {
 					continue;
 				}		
 				TypeBinding castedExpressionType = ((CastExpression)argument).expression.resolvedType;
@@ -162,7 +162,7 @@
 		// check need for left operand cast
 		int alternateLeftTypeId = leftTypeId;
 		if (leftIsCast) {
-			if ((left.bits & UnnecessaryCastMask) == 0 && left.resolvedType.isBaseType()) {
+			if ((left.bits & UnnecessaryCastMASK) == 0 && left.resolvedType.isBaseType()) {
  				// narrowing conversion on base type may change value, thus necessary
  				leftIsCast = false;
 			} else  {
@@ -180,7 +180,7 @@
 		// check need for right operand cast
 		int alternateRightTypeId = rightTypeId;
 		if (rightIsCast) {
-			if ((right.bits & UnnecessaryCastMask) == 0 && right.resolvedType.isBaseType()) {
+			if ((right.bits & UnnecessaryCastMASK) == 0 && right.resolvedType.isBaseType()) {
  				// narrowing conversion on base type may change value, thus necessary
  				rightIsCast = false;
 			} else {
@@ -211,8 +211,8 @@
 			//  <<16   <<12       <<8    <<4       <<0
 			final int CompareMASK = (0xF<<16) + (0xF<<8) + 0xF; // mask hiding compile-time types
 			if ((operatorSignature & CompareMASK) == (alternateOperatorSignature & CompareMASK)) { // same promotions and result
-				if (leftIsCast) scope.problemReporter().unnecessaryCastForArgument((CastExpression)left,  TypeBinding.wellKnownType(scope, (left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4)); 
-				if (rightIsCast) scope.problemReporter().unnecessaryCastForArgument((CastExpression)right, TypeBinding.wellKnownType(scope,  (right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4));
+				if (leftIsCast) scope.problemReporter().unnecessaryCast((CastExpression)left); 
+				if (rightIsCast) scope.problemReporter().unnecessaryCast((CastExpression)right);
 			}
 		}
 	}
@@ -240,7 +240,7 @@
 			if (bindingIfNoCast == binding) {
 				for (int i = 0, length = originalArgumentTypes.length; i < length; i++) {
 					if (originalArgumentTypes[i] != alternateArgumentTypes[i]) {
-						scope.problemReporter().unnecessaryCastForArgument((CastExpression)arguments[i], binding.parameters[i]);
+						scope.problemReporter().unnecessaryCast((CastExpression)arguments[i]);
 					}
 				}
 			}	
@@ -253,24 +253,23 @@
 			}
 			return true;
 		}
-		if (castType.isBoundParameterizedType() || castType.isGenericType()) {
+		if (match != null && (castType.isBoundParameterizedType() || castType.isGenericType() || expressionType.isBoundParameterizedType() || expressionType.isGenericType())) {
 			if (match.isProvablyDistinctFrom(isNarrowing ? expressionType : castType, 0)) {
-				reportIllegalCast(scope, castType, expressionType);
 				return false; 
 			}
 			if (isNarrowing ? !expressionType.isEquivalentTo(match) : !match.isEquivalentTo(castType)) {
-				scope.problemReporter().unsafeCast(this, scope);
+				this.bits |= UnsafeCastMask;
 				return true;
 			}
 			if ((castType.tagBits & TagBits.HasDirectWildcard) == 0) {
 				if ((!match.isParameterizedType() && !match.isGenericType())
 						|| expressionType.isRawType()) {
-					scope.problemReporter().unsafeCast(this, scope);
+					this.bits |= UnsafeCastMask;
 					return true;
 				}
 			}
 		} else if (isNarrowing && castType.isTypeVariable()) {
-			scope.problemReporter().unsafeCast(this, scope);
+			this.bits |= UnsafeCastMask;
 			return true;
 		}
 		if (!isNarrowing && castType == this.resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
@@ -352,10 +351,6 @@
 		return expression.printExpression(0, output);
 	}
 
-	public void reportIllegalCast(Scope scope, TypeBinding castType, TypeBinding expressionType) {
-		scope.problemReporter().typeCastError(this, castType, expressionType);
-	}
-	
 	public TypeBinding resolveType(BlockScope scope) {
 		// compute a new constant if the cast is effective
 
@@ -373,13 +368,18 @@
 			expression.setExpectedType(this.resolvedType); // needed in case of generic method invocation			
 			TypeBinding expressionType = expression.resolveType(scope);
 			if (this.resolvedType != null && expressionType != null) {
-				checkCastTypesCompatibility(scope, this.resolvedType, expressionType, this.expression);
+				boolean isLegal = checkCastTypesCompatibility(scope, this.resolvedType, expressionType, this.expression);
 				this.expression.computeConversion(scope, this.resolvedType, expressionType);
-				if ((this.bits & UnnecessaryCastMask) != 0) {
-					if ((this.bits & IgnoreNeedForCastCheckMASK) == 0) {
-						if (!usedForGenericMethodReturnTypeInference()) // used for generic type inference ?
+				if (isLegal) {
+					if ((this.bits & UnsafeCastMask) != 0) { // unsafe cast
+						scope.problemReporter().unsafeCast(this, scope);
+					} else if ((this.bits & (UnnecessaryCastMASK|IgnoreNeedForCastCheckMASK)) == UnnecessaryCastMASK) { // unnecessary cast 
+						if (!isIndirectlyUsed()) // used for generic type inference or boxing ?
 							scope.problemReporter().unnecessaryCast(this);
 					}
+					this.resolvedType = this.resolvedType.capture();
+				} else { // illegal cast
+					scope.problemReporter().typeCastError(this,  this.resolvedType, expressionType);
 				}
 			}
 			return this.resolvedType;
@@ -400,9 +400,9 @@
 
 	/**
 	 * Determines whether apparent unnecessary cast wasn't actually used to
-	 * perform return type inference of generic method invocation.
+	 * perform return type inference of generic method invocation or boxing.
 	 */
-	private boolean usedForGenericMethodReturnTypeInference() {
+	private boolean isIndirectlyUsed() {
 		if (this.expression instanceof MessageSend) {
 			MethodBinding method = ((MessageSend)this.expression).binding;
 			if (method instanceof ParameterizedGenericMethodBinding
@@ -413,6 +413,10 @@
 					return true;
 			}
 		}
+		if (this.expectedType != null && this.resolvedType.isBaseType() && !this.resolvedType.isCompatibleWith(this.expectedType)) {
+			// boxing: Short s = (short) _byte
+			return true;
+		}
 		return false;
 	}
 
@@ -428,7 +432,7 @@
 	 */
 	public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
 		if (this.expression.resolvedType == null) return; // cannot do better if expression is not bound
-		this.bits |= UnnecessaryCastMask;
+		this.bits |= UnnecessaryCastMASK;
 	}
 	
 	public void traverse(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java
index 8aad9ab..de69a08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
index 4e35315..c3af69f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -87,7 +87,16 @@
 		ReferenceBinding classType = scope.getJavaLangClass();
 		if (classType.isGenericType()) {
 		    // Integer.class --> Class<Integer>, perform boxing of base types (int.class --> Class<Integer>)
-		    this.resolvedType = scope.createParameterizedType(classType, new TypeBinding[]{ scope.boxing(targetType) }, null/*not a member*/);
+			TypeBinding boxedType = null;
+			if (targetType.id == T_void) {
+				boxedType = scope.environment().getType(JAVA_LANG_VOID);
+				if (boxedType == null) {
+					boxedType = new ProblemReferenceBinding(JAVA_LANG_VOID, ProblemReasons.NotFound);
+				}
+			} else {
+				boxedType = scope.boxing(targetType);
+			}
+		    this.resolvedType = scope.createParameterizedType(classType, new TypeBinding[]{ boxedType }, null/*not a member*/);
 		} else {
 		    this.resolvedType = classType;
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
index 22dbe6d..b51b130 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -164,9 +164,10 @@
 		}
 		// generate static fields/initializers/enum constants
 		final FieldDeclaration[] fieldDeclarations = declaringType.fields;
+		BlockScope lastInitializerScope = null;
 		if (declaringType.kind() == IGenericType.ENUM_DECL) {
 			int enumCount = 0;
-			int notEnumConstants = 0;
+			int remainingFieldCount = 0;
 			if (fieldDeclarations != null) {
 				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
 					FieldDeclaration fieldDecl = fieldDeclarations[i];
@@ -175,7 +176,7 @@
 							fieldDecl.generateCode(staticInitializerScope, codeStream);
 							enumCount++;
 						} else {
-							notEnumConstants++;
+							remainingFieldCount++;
 						}
 					}
 				}
@@ -199,12 +200,25 @@
 					codeStream.putstatic(declaringType.enumValuesSyntheticfield);
 				}
 			}
-			if (notEnumConstants != 0) {
+			if (remainingFieldCount != 0) {
 				// if fields that are not enum constants need to be generated (static initializer/static field)
 				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
 					FieldDeclaration fieldDecl = fieldDeclarations[i];
-					if (fieldDecl.isStatic() && fieldDecl.getKind() != AbstractVariableDeclaration.ENUM_CONSTANT) {
-						fieldDecl.generateCode(staticInitializerScope, codeStream);
+					switch (fieldDecl.getKind()) {
+						case AbstractVariableDeclaration.ENUM_CONSTANT :
+							break;
+						case AbstractVariableDeclaration.INITIALIZER :
+							if (!fieldDecl.isStatic()) 
+								break;
+							lastInitializerScope = ((Initializer) fieldDecl).block.scope;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
+						case AbstractVariableDeclaration.FIELD :
+							if (!fieldDecl.binding.isStatic()) 
+								break;
+							lastInitializerScope = null;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
 					}
 				}
 			}
@@ -212,8 +226,19 @@
 			if (fieldDeclarations != null) {
 				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
 					FieldDeclaration fieldDecl = fieldDeclarations[i];
-					if (fieldDecl.isStatic()) {
-						fieldDecl.generateCode(staticInitializerScope, codeStream);
+					switch (fieldDecl.getKind()) {
+						case AbstractVariableDeclaration.INITIALIZER :
+							if (!fieldDecl.isStatic()) 
+								break;
+							lastInitializerScope = ((Initializer) fieldDecl).block.scope;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
+						case AbstractVariableDeclaration.FIELD :
+							if (!fieldDecl.binding.isStatic()) 
+								break;
+							lastInitializerScope = null;
+							fieldDecl.generateCode(staticInitializerScope, codeStream);
+							break;
 					}
 				}
 			}
@@ -229,9 +254,12 @@
 			constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
 		} else {
 			if (this.needFreeReturn) {
-				int oldPosition = codeStream.position;
+				int before = codeStream.position;
 				codeStream.return_();
-				codeStream.updateLocalVariablesAttribute(oldPosition);
+				if (lastInitializerScope != null) {
+					// expand the last initializer variables to include the trailing return
+					codeStream.updateLastRecordedEndPC(lastInitializerScope, before);
+				}
 			}
 			// Record the end of the clinit: point to the declaration of the class
 			codeStream.recordPositionsFrom(0, declaringType.sourceStart);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index df96e49..363754d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,9 +19,7 @@
 public class CompilationUnitDeclaration
 	extends ASTNode
 	implements ProblemSeverities, ReferenceContext {
-	
-	private static final char[] PACKAGE_INFO_FILE_NAME = "package-info.java".toCharArray(); //$NON-NLS-1$
-		
+
 	public ImportReference currentPackage;
 	public ImportReference[] imports;
 	public TypeDeclaration[] types;
@@ -101,6 +99,7 @@
 			    LocalTypeBinding localType = localTypes[i];
 				// null out the type's scope backpointers
 				localType.scope = null; // local members are already in the list
+				localType.enclosingCase = null;
 			}
 		}
 		ClassFile[] classFiles = compilationResult.getClassFiles();
@@ -174,6 +173,9 @@
 			}
 			return;
 		}
+		if (this.isPackageInfo() && this.types != null) {
+			types[0].annotations = this.currentPackage.annotations;
+		}
 		try {
 			if (types != null) {
 				for (int i = 0, count = types.length; i < count; i++)
@@ -213,6 +215,12 @@
 		return (currentPackage == null) && (imports == null) && (types == null);
 	}
 
+	public boolean isPackageInfo() {
+		return CharOperation.equals(this.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)
+			&& this.currentPackage != null
+			&& this.currentPackage.annotations != null;
+	}
+	
 	public boolean hasErrors() {
 		return this.ignoreFurtherInvestigation;
 	}
@@ -268,15 +276,27 @@
 	}
 
 	public void resolve() {
+		int startingTypeIndex = 0;
 		if (this.currentPackage != null) {
-			if (this.currentPackage.annotations != null
-					&& !CharOperation.endsWith(getFileName(), PACKAGE_INFO_FILE_NAME)) {
-				scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]);
+			if (this.currentPackage.annotations != null) {
+				if (CharOperation.equals(this.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) {
+                    if (this.types != null) {
+                        // resolve annotations
+    					final TypeDeclaration syntheticTypeDeclaration = types[0];
+    					syntheticTypeDeclaration.resolve(this.scope);
+    					resolveAnnotations(syntheticTypeDeclaration.staticInitializerScope, this.currentPackage.annotations, this.scope.fPackage);
+    					// set the synthetic bit
+    					syntheticTypeDeclaration.binding.modifiers |= AccSynthetic;
+    					startingTypeIndex = 1;
+                    }
+				} else {
+					scope.problemReporter().invalidFileNameForPackageAnnotations(this.currentPackage.annotations[0]);
+				}
 			}
 		}
 		try {
 			if (types != null) {
-				for (int i = 0, count = types.length; i < count; i++) {
+				for (int i = startingTypeIndex, count = types.length; i < count; i++) {
 					types[i].resolve(scope);
 				}
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
index 8e0f2f3..5135167 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -160,10 +160,10 @@
 			}
 		}
 		this.lhs.implicitConversion = (unboxedLhs ? UNBOXING : 0) | (result >>> 12);
-		scope.problemReporter().autoboxing(this.lhs, originalLhsType, lhsType);
+		if (unboxedLhs) scope.problemReporter().autoboxing(this.lhs, originalLhsType, lhsType);
 		this.expression.computeConversion(scope, TypeBinding.wellKnownType(scope, (result >>> 8) & 0x0000F), originalExpressionType);
 		this.assignmentImplicitConversion =  (unboxedLhs ? BOXING : 0) | (lhsID << 4) | (result & 0x0000F);
-		scope.problemReporter().autoboxing(this, lhsType, originalLhsType);
+		if (unboxedLhs) scope.problemReporter().autoboxing(this, lhsType, originalLhsType);
 		return this.resolvedType = originalLhsType;
 	}
 	
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index 2572232..8dddb92 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -159,7 +159,7 @@
 				// Jump over the else part
 				int position = codeStream.position;
 				codeStream.goto_(endifLabel);
-				codeStream.updateLastRecordedEndPC(position);
+				codeStream.updateLastRecordedEndPC(currentScope, position);
 				// Tune codestream stack size
 				if (valueRequired) {
 					codeStream.decrStackSize(this.resolvedType == LongBinding || this.resolvedType == DoubleBinding ? 2 : 1);
@@ -239,7 +239,7 @@
 				// Jump over the else part
 				int position = codeStream.position;
 				codeStream.goto_(endifLabel);
-				codeStream.updateLastRecordedEndPC(position);
+				codeStream.updateLastRecordedEndPC(currentScope, position);
 				// No need to decrement codestream stack size
 				// since valueIfTrue was already consumed by branch bytecode
 			}
@@ -260,7 +260,7 @@
 			codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
 		}
 		// no implicit conversion for boolean values
-		codeStream.updateLastRecordedEndPC(codeStream.position);
+		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 	}
 
 	public Constant optimizedBooleanConstant() {
@@ -294,12 +294,21 @@
 		TypeBinding valueIfTrueType = originalValueIfTrueType;
 		TypeBinding valueIfFalseType = originalValueIfFalseType;
 		if (use15specifics) {
-			if (valueIfTrueType != NullBinding && valueIfTrueType.isBaseType()) {
-				if (!valueIfFalseType.isBaseType()) {
-					valueIfFalseType = env.computeBoxingType(valueIfFalseType);
+			if (valueIfTrueType != valueIfFalseType) {
+				TypeBinding unboxedIfTrueType = valueIfTrueType.isBaseType() ? valueIfTrueType : env.computeBoxingType(valueIfTrueType);
+				TypeBinding unboxedIfFalseType = valueIfFalseType.isBaseType() ? valueIfFalseType : env.computeBoxingType(valueIfFalseType);
+				if (unboxedIfTrueType.isNumericType() && unboxedIfFalseType.isNumericType()) {
+					valueIfTrueType = unboxedIfTrueType;
+					valueIfFalseType = unboxedIfFalseType;
+				} else if (valueIfTrueType.isBaseType()) {
+					if ((valueIfTrueType == NullBinding) == valueIfFalseType.isBaseType()) {  // bool ? null : 12 --> Integer
+						valueIfFalseType = env.computeBoxingType(valueIfFalseType);
+					}
+				} else if (valueIfFalseType.isBaseType()) {
+					if ((valueIfFalseType == NullBinding) == valueIfTrueType.isBaseType()) {  // bool ? 12 : null --> Integer
+						valueIfTrueType = env.computeBoxingType(valueIfTrueType);
+					}
 				}
-			} else if (valueIfFalseType != NullBinding && valueIfFalseType.isBaseType()) {
-				valueIfTrueType = env.computeBoxingType(valueIfTrueType);
 			}
 		}
 		// Propagate the constant value from the valueIfTrue and valueIFFalse expression if it is possible
@@ -308,7 +317,7 @@
 			&& (trueConstant = valueIfTrue.constant) != NotAConstant
 			&& (falseConstant = valueIfFalse.constant) != NotAConstant) {
 			// all terms are constant expression so we can propagate the constant
-			// from valueIFTrue or valueIfFalse to teh receiver constant
+			// from valueIFTrue or valueIfFalse to the receiver constant
 			constant = condConstant.booleanValue() ? trueConstant : falseConstant;
 		}
 		if (valueIfTrueType == valueIfFalseType) { // harmed the implicit conversion 
@@ -409,7 +418,7 @@
 			if (commonType != null) {
 				valueIfTrue.computeConversion(scope, commonType, valueIfTrueType);
 				valueIfFalse.computeConversion(scope, commonType, valueIfFalseType);
-				return this.resolvedType = commonType;
+				return this.resolvedType = commonType.capture();
 			}
 		}
 		scope.problemReporter().conditionalArgumentsIncompatibleTypes(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 892b91b..7346dce 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
index 83831b3..954db08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
index a12254a..80bd55c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java
index 1c8a8c1..51cd7f4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
index bd570e6..9414844 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 4b2fec9..4f1cea4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -145,7 +145,8 @@
 				// comparison is TRUE 
 				codeStream.iconst_1();
 				if ((bits & ValueForReturnMASK) != 0){
-					codeStream.ireturn();
+					codeStream.generateImplicitConversion(this.implicitConversion);
+					codeStream.generateReturnBytecode(this);
 					// comparison is FALSE
 					falseLabel.place();
 					codeStream.iconst_0();
@@ -225,7 +226,7 @@
 			}
 		}
 		// reposition the endPC
-		codeStream.updateLastRecordedEndPC(codeStream.position);					
+		codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);					
 	}
 	/**
 	 * Boolean generation for == with non-boolean operands
@@ -461,8 +462,10 @@
 	
 		// Object references 
 		// spec 15.20.3
-		if (this.checkCastTypesCompatibility(scope, leftType, rightType, null) 
-				|| this.checkCastTypesCompatibility(scope, rightType, leftType, null)) {
+		if ((!leftType.isBaseType() || leftType == NullBinding) // cannot compare: Object == (int)0
+				&& (!rightType.isBaseType() || rightType == NullBinding)
+				&& (this.checkCastTypesCompatibility(scope, leftType, rightType, null) 
+						|| this.checkCastTypesCompatibility(scope, rightType, leftType, null))) {
 
 			// (special case for String)
 			if ((rightType.id == T_JavaLangString) && (leftType.id == T_JavaLangString)) {
@@ -474,8 +477,8 @@
 			left.computeConversion(scope, objectType, leftType);
 			right.computeConversion(scope, objectType, rightType);
 			// check need for operand cast
-			boolean unnecessaryLeftCast = (left.bits & UnnecessaryCastMask) != 0;
-			boolean unnecessaryRightCast = (right.bits & UnnecessaryCastMask) != 0;
+			boolean unnecessaryLeftCast = (left.bits & UnnecessaryCastMASK) != 0;
+			boolean unnecessaryRightCast = (right.bits & UnnecessaryCastMASK) != 0;
 			if (unnecessaryLeftCast || unnecessaryRightCast) {
 				TypeBinding alternateLeftType = unnecessaryLeftCast ? ((CastExpression)left).expression.resolvedType : leftType;
 				TypeBinding alternateRightType = unnecessaryRightCast ? ((CastExpression)right).expression.resolvedType : rightType;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index a0b814e..ac86e95 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -327,8 +327,7 @@
 			if ((binding = scope.getConstructor(receiverType, argumentTypes, this)).isValidBinding()) {
 				if (isMethodUseDeprecated(binding, scope))
 					scope.problemReporter().deprecatedMethod(binding, this);
-				if (this.arguments != null)
-					checkInvocationArguments(scope, null, receiverType, binding, this.arguments, argumentTypes, argsContainCast, this);
+				checkInvocationArguments(scope, null, receiverType, binding, this.arguments, argumentTypes, argsContainCast, this);
 				if (binding.isPrivate()) {
 					binding.original().modifiers |= AccPrivateUsed;
 				}				
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 3b93b9d..85fb5bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,7 +19,7 @@
 import org.eclipse.jdt.internal.compiler.flow.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.problem.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 
 public abstract class Expression extends Statement {
 	
@@ -246,19 +246,17 @@
 					return true;
 					
 				}
-			} else if (use15specifics) { // unboxing - only exact match is allowed
-				if (env.computeBoxingType(expressionType) == castType) {
-					// TODO (philippe) could tagAsUnnecessaryCast(scope, castType);  
-					return true;
-				}
-			}
-			reportIllegalCast(scope, castType, expressionType);
-			return false;
-		} else if (use15specifics && expressionType.isBaseType()) { // boxing - only exact match is allowed
-			if (env.computeBoxingType(castType) == expressionType) {
-				// TODO (philippe) could tagAsUnnecessaryCast(scope, castType);  
+			} else if (use15specifics 
+								&& env.computeBoxingType(expressionType).isCompatibleWith(castType)) { // unboxing - only widening match is allowed
+				tagAsUnnecessaryCast(scope, castType);  
 				return true;
 			}
+			return false;
+		} else if (use15specifics 
+							&& expressionType.isBaseType() 
+							&& env.computeBoxingType(expressionType).isCompatibleWith(castType)) { // boxing - only widening match is allowed
+			tagAsUnnecessaryCast(scope, castType);  
+			return true;
 		}
 	
 		//-----------cast to something which is NOT a base type--------------------------	
@@ -267,7 +265,6 @@
 			return true; //null is compatible with every thing
 		}
 		if (expressionType.isBaseType()) {
-			reportIllegalCast(scope, castType, expressionType);
 			return false;
 		}
 	
@@ -279,35 +276,31 @@
 	
 			if (castType.isArrayType()) {
 				//------- (castType.isArray) expressionType.isArray -----------
+				TypeBinding castElementType = ((ArrayBinding) castType).elementsType();
 				TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType();
-				if (exprElementType.isBaseType()) {
+				if (exprElementType.isBaseType() || castElementType.isBaseType()) {
 					// <---stop the recursion------- 
-					if (((ArrayBinding) castType).elementsType() == exprElementType) {
+					if (castElementType == exprElementType) {
 						tagAsNeedCheckCast();
 						return true;
 					} else {
-						reportIllegalCast(scope, castType, expressionType);
 						return false;
 					}
 				}
 				// recursively on the elements...
-				return checkCastTypesCompatibility(
-					scope,
-					((ArrayBinding) castType).elementsType(),
-					exprElementType,
-					expression);
+				return checkCastTypesCompatibility(scope, ((ArrayBinding) castType).elementsType(), exprElementType, expression);
 			} else if (castType.isTypeVariable()) {
-				TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
-				if (match == null) {
-					checkUnsafeCast(scope, castType, expressionType, match, true);
+				if (expressionType instanceof ReferenceBinding) {
+					ReferenceBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
+					if (match == null) {
+						checkUnsafeCast(scope, castType, expressionType, match, true);
+					}
+				} else {
+					checkUnsafeCast(scope, castType, expressionType, null, true);
 				}
 				// recursively on the type variable upper bound
-				return checkCastTypesCompatibility(
-					scope,
-					castType.erasure(),
-					expressionType,
-					expression);
-			} else if (castType.isClass()) {
+				return checkCastTypesCompatibility(scope, castType.erasure(), expressionType, expression);
+			} else if (castType.isClass() || castType.isEnum()) {
 				//------(castType.isClass) expressionType.isArray ---------------	
 				if (castType.id == T_JavaLangObject) {
 					tagAsUnnecessaryCast(scope, castType);
@@ -319,24 +312,21 @@
 					return true;
 				}
 			}
-			reportIllegalCast(scope, castType, expressionType);
 			return false;
 		}
 		if (expressionType.isTypeVariable() || expressionType.isWildcard()) {
-			TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
-			if (match != null) {
-				tagAsUnnecessaryCast(scope, castType);
-				return true;
+			if (castType instanceof ReferenceBinding) {
+				TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType);
+				if (match != null) {
+					tagAsUnnecessaryCast(scope, castType);
+					return true;
+				}
 			}
 			// recursively on the type variable upper bound
-			return checkCastTypesCompatibility(
-				scope,
-				castType,
-				expressionType.erasure(),
-				expression);
+			return checkCastTypesCompatibility(scope, castType, expressionType.erasure(), expression);
 		}
 		
-		if (expressionType.isClass()) {
+		if (expressionType.isClass() || expressionType.isEnum()) {
 			if (castType.isArrayType()) {
 				// ---- (castType.isArray) expressionType.isClass -------
 				if (expressionType.id == T_JavaLangObject) { // potential runtime error
@@ -349,12 +339,8 @@
 					checkUnsafeCast(scope, castType, expressionType, match, true);
 				}
 				// recursively on the type variable upper bound
-				return checkCastTypesCompatibility(
-					scope,
-					castType.erasure(),
-					expressionType,
-					expression);
-			} else if (castType.isClass()) { // ----- (castType.isClass) expressionType.isClass ------
+				return checkCastTypesCompatibility(scope, castType.erasure(), expressionType, expression);
+			} else if (castType.isClass() || castType.isEnum()) { // ----- (castType.isClass) expressionType.isClass ------
 				TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType.erasure());
 				if (match != null) {
 					if (expression != null && castType.id == T_JavaLangString) this.constant = expression.constant; // (String) cst is still a constant
@@ -382,7 +368,6 @@
 				}
 				// no subclass for expressionType, thus compile-time check is valid
 			}
-			reportIllegalCast(scope, castType, expressionType);
 			return false;
 		}
 	
@@ -394,7 +379,6 @@
 				tagAsNeedCheckCast();
 				return true;
 			} else {
-				reportIllegalCast(scope, castType, expressionType);
 				return false;
 			}
 		} else if (castType.isTypeVariable()) {
@@ -403,12 +387,8 @@
 				checkUnsafeCast(scope, castType, expressionType, match, true);
 			}
 			// recursively on the type variable upper bound
-			return checkCastTypesCompatibility(
-				scope,
-				castType.erasure(),
-				expressionType,
-				expression);
-		} else if (castType.isClass()) { // ----- (castType.isClass) expressionType.isInterface --------
+			return checkCastTypesCompatibility(scope, castType.erasure(), expressionType, expression);
+		} else if (castType.isClass() || castType.isEnum()) { // ----- (castType.isClass) expressionType.isInterface --------
 
 			if (castType.id == T_JavaLangObject) { // no runtime error
 				tagAsUnnecessaryCast(scope, castType);
@@ -419,38 +399,39 @@
 				TypeBinding match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)expressionType.erasure());
 				if (match == null) {
 					// potential runtime error
-					reportIllegalCast(scope, castType, expressionType);
 					return false;
 				}				
 			}
 		} else { // ----- (castType.isInterface) expressionType.isInterface -------
-
-			TypeBinding match = ((ReferenceBinding)expressionType).findSuperTypeErasingTo((ReferenceBinding)castType.erasure());
-			if (match != null) {
-				return checkUnsafeCast(scope, castType, expressionType, match, false);
-			}
-			
-			match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)expressionType.erasure());
-			if (match != null) {
+				ReferenceBinding interfaceType = (ReferenceBinding) expressionType;
+				TypeBinding match = interfaceType.findSuperTypeErasingTo((ReferenceBinding)castType.erasure());
+				if (match != null) {
+					return checkUnsafeCast(scope, castType, interfaceType, match, false);
+				}
+				
 				tagAsNeedCheckCast();
-				return checkUnsafeCast(scope, castType, expressionType, match, true);
-			}  else {
+				match = ((ReferenceBinding)castType).findSuperTypeErasingTo((ReferenceBinding)interfaceType.erasure());
+				if (match != null) {
+					return checkUnsafeCast(scope, castType, interfaceType, match, true);
+				}
+				if (use15specifics) {
+					// a subclass may implement the interface ==> no check at compile time
+					return true;
+				}
+				// pre1.5 semantics - no covariance allowed (even if 1.5 compliant, but 1.4 source)
 				MethodBinding[] castTypeMethods = getAllInheritedMethods((ReferenceBinding) castType);
-				MethodBinding[] expressionTypeMethods =
-					getAllInheritedMethods((ReferenceBinding) expressionType);
+				MethodBinding[] expressionTypeMethods = getAllInheritedMethods((ReferenceBinding) expressionType);
 				int exprMethodsLength = expressionTypeMethods.length;
-				for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++) {
+				for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++)
 					for (int j = 0; j < exprMethodsLength; j++) {
 						if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType)
 								&& (CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector))
 								&& castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) {
-							reportIllegalCast(scope, castType, expressionType);
 							return false;
 
 						}
 					}
-				}
-			}
+				return true;
 		}
 		tagAsNeedCheckCast();
 		return true;
@@ -502,9 +483,8 @@
 			if (!isNarrowing) tagAsUnnecessaryCast(scope, castType);
 			return true;
 		}
-		if (castType.isBoundParameterizedType() || castType.isGenericType()) {
+		if (match != null && (castType.isBoundParameterizedType() || castType.isGenericType() || expressionType.isBoundParameterizedType() || expressionType.isGenericType())) {
 			if (match.isProvablyDistinctFrom(isNarrowing ? expressionType : castType, 0)) {
-				reportIllegalCast(scope, castType, expressionType);
 				return false; 
 			}
 		}
@@ -538,7 +518,7 @@
 				if (boxedType == runtimeTimeType) // Object o = 12;
 					boxedType = compileTimeType; 
 				this.implicitConversion = BOXING | (boxedType.id << 4) + compileTimeType.id;
-				scope.problemReporter().autoboxing(this, compileTimeType, runtimeTimeType);
+				scope.problemReporter().autoboxing(this, compileTimeType, scope.environment().computeBoxingType(boxedType));
 				return;
 			}
 		}
@@ -597,7 +577,7 @@
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
 		} else {
 			// actual non-constant code generation
-			throw new ShouldNotImplement(Util.bind("ast.missingCode")); //$NON-NLS-1$
+			throw new ShouldNotImplement(Messages.ast_missingCode); 
 		}
 	}
 
@@ -663,7 +643,7 @@
 			}
 		}
 		// reposition the endPC
-		codeStream.updateLastRecordedEndPC(position);
+		codeStream.updateLastRecordedEndPC(currentScope, position);
 	}
 
 	/* Optimized (java) code generation for string concatenations that involve StringBuffer
@@ -794,10 +774,6 @@
 		return print(indent, output).append(";"); //$NON-NLS-1$
 	}
 
-	public void reportIllegalCast(Scope scope, TypeBinding castType, TypeBinding expressionType) {
-		// do nothing by default
-	}
-	
 	public void resolve(BlockScope scope) {
 		// drops the returning expression's type whatever the type is.
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
index 68b8fde..71a34dc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java
index 6219111..5cec3a9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index 576d51a..552abcb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -67,7 +67,7 @@
 				&& this.binding.isStatic()
 				&& !this.binding.isConstantValue()
 				&& this.binding.declaringClass.isNestedType()
-				&& this.binding.declaringClass.isClass()
+				&& this.binding.declaringClass.isClass() // no need to check for enum, since implicitly static
 				&& !this.binding.declaringClass.isStatic()) {
 			initializationScope.problemReporter().unexpectedStaticModifierForField(
 				(SourceTypeBinding) this.binding.declaringClass,
@@ -141,7 +141,14 @@
 			return this.binding.isStatic();
 		return (this.modifiers & AccStatic) != 0;
 	}
-	
+
+	public StringBuffer printStatement(int indent, StringBuffer output) {
+		if (this.javadoc != null) {
+			this.javadoc.print(indent, output);
+		}
+		return super.printStatement(indent, output);
+	}
+
 	public void resolve(MethodScope initializationScope) {
 
 		// the two <constant = Constant.NotAConstant> could be regrouped into
@@ -220,7 +227,7 @@
 								|| initializationType.isCompatibleWith(fieldType)) {
 							this.initialization.computeConversion(initializationScope, fieldType, initializationType);
 							if (initializationType.needsUncheckedConversion(fieldType)) {
-								    initializationScope.problemReporter().unsafeRawConversion(this.initialization, initializationType, fieldType);
+								    initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType);
 							}									
 						} else if (initializationScope.environment().options.sourceLevel >= JDK1_5 // autoboxing
 										&& (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
index 1e00105..f1157b3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -116,7 +116,7 @@
 		receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic);
 		if (nonStatic) receiver.checkNullStatus(currentScope, flowContext, flowInfo, FlowInfo.NON_NULL);
 		
-		if (valueRequired) {
+		if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
 			manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
 		}
 		return flowInfo;
@@ -134,7 +134,10 @@
 			if (originalBinding != this.binding) {
 			    // extra cast needed if method return type has type variable
 			    if ((originalBinding.type.tagBits & TagBits.HasTypeVariable) != 0 && runtimeTimeType.id != T_JavaLangObject) {
-			        this.genericCast = originalBinding.type.genericCast(scope.boxing(runtimeTimeType)); // runtimeType could be base type in boxing case
+			    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 
+			    		? compileTimeType  // unboxing: checkcast before conversion
+			    		: runtimeTimeType;
+			        this.genericCast = originalBinding.type.genericCast(targetType);
 			    }
 			}
 		} 	
@@ -152,10 +155,12 @@
 		Assignment assignment,
 		boolean valueRequired) {
 
+		int pc = codeStream.position;
 		receiver.generateCode(
 			currentScope,
 			codeStream,
 			!this.codegenBinding.isStatic());
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
 		assignment.expression.generateCode(currentScope, codeStream, true);
 		fieldStore(
 			codeStream,
@@ -187,11 +192,26 @@
 			}
 		} else {
 			boolean isStatic = this.codegenBinding.isStatic();
-			receiver.generateCode(currentScope, codeStream, !isStatic);
-			if (valueRequired) {
-				if (!this.codegenBinding.isConstantValue()) {
+			if (this.codegenBinding.isConstantValue()) {
+				receiver.generateCode(currentScope, codeStream, !isStatic);
+				if (!isStatic){
+					codeStream.invokeObjectGetClass();
+					codeStream.pop();
+				}
+				if (valueRequired) {
+					codeStream.generateConstant(this.codegenBinding.constant(), implicitConversion);
+				}
+			} else {
+				receiver.generateCode(currentScope, codeStream, !isStatic);
+				if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
 					if (this.codegenBinding.declaringClass == null) { // array length
 						codeStream.arraylength();
+						if (valueRequired) {
+							codeStream.generateImplicitConversion(implicitConversion);
+						} else {
+							// could occur if !valueRequired but compliance >= 1.4
+							codeStream.pop();
+						}
 					} else {
 						if (syntheticAccessors == null || syntheticAccessors[READ] == null) {
 							if (isStatic) {
@@ -202,20 +222,26 @@
 						} else {
 							codeStream.invokestatic(syntheticAccessors[READ]);
 						}
+						if (valueRequired) {
+							if (this.genericCast != null) codeStream.checkcast(this.genericCast);			
+							codeStream.generateImplicitConversion(implicitConversion);
+						} else {
+							// could occur if !valueRequired but compliance >= 1.4
+							switch (this.codegenBinding.type.id) {
+								case T_long :
+								case T_double :
+									codeStream.pop2();
+									break;
+								default :
+									codeStream.pop();
+							}
+						}
 					}
-					if (this.genericCast != null) codeStream.checkcast(this.genericCast);			
-					codeStream.generateImplicitConversion(implicitConversion);
 				} else {
-					if (!isStatic) {
+					if (!isStatic){
 						codeStream.invokeObjectGetClass(); // perform null check
 						codeStream.pop();
 					}
-					codeStream.generateConstant(this.codegenBinding.constant(), implicitConversion);
-				}
-			} else {
-				if (!isStatic){
-					codeStream.invokeObjectGetClass(); // perform null check
-					codeStream.pop();
 				}
 			}
 		}
@@ -452,19 +478,23 @@
 		// if the binding declaring class is not visible, need special action
 		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
 		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
+		// and not from Object or implicit static field access.	
 		if (this.binding.declaringClass != this.receiverType
-			&& !this.receiverType.isArrayType()
-			&& this.binding.declaringClass != null // array.length
-			&& !this.binding.isConstantValue()
-			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
-				&& this.binding.declaringClass.id != T_JavaLangObject)
-			//no change for Object fields (in case there was)
-				|| !this.codegenBinding.declaringClass.canBeSeenBy(currentScope))) {
-			this.codegenBinding =
-				currentScope.enclosingSourceType().getUpdatedFieldBinding(
-					this.codegenBinding,
-					(ReferenceBinding) this.receiverType.erasure());
-		}
+				&& !this.receiverType.isArrayType()
+				&& this.binding.declaringClass != null // array.length
+				&& !this.binding.isConstantValue()) {
+			CompilerOptions options = currentScope.environment().options;
+			if ((options.targetJDK >= ClassFileConstants.JDK1_2
+					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
+					&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields
+				|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
+	
+				this.codegenBinding =
+					currentScope.enclosingSourceType().getUpdatedFieldBinding(
+						this.codegenBinding,
+						(ReferenceBinding) this.receiverType.erasure());
+			}
+		}		
 	}
 
 
@@ -497,33 +527,44 @@
 			}
 		}		
 		// the case receiverType.isArrayType and token = 'length' is handled by the scope API
-		this.codegenBinding = this.binding = scope.getField(this.receiverType, token, this);
-		if (!binding.isValidBinding()) {
+		FieldBinding fieldBinding = this.codegenBinding = this.binding = scope.getField(this.receiverType, token, this);
+		if (!fieldBinding.isValidBinding()) {
 			constant = NotAConstant;
 			scope.problemReporter().invalidField(this, this.receiverType);
 			return null;
 		}
+		TypeBinding receiverErasure = this.receiverType.erasure();
+		if (receiverErasure instanceof ReferenceBinding) {
+			ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo((ReferenceBinding)fieldBinding.declaringClass.erasure());
+			if (match == null) {
+				this.receiverType = fieldBinding.declaringClass; // handle indirect inheritance thru variable secondary bound
+			}
+		}
 		this.receiver.computeConversion(scope, this.receiverType, this.receiverType);
-		if (isFieldUseDeprecated(binding, scope, (this.bits & IsStrictlyAssignedMASK) !=0)) {
-			scope.problemReporter().deprecatedField(binding, this);
+		if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssignedMASK) !=0)) {
+			scope.problemReporter().deprecatedField(fieldBinding, this);
 		}
 		boolean isImplicitThisRcv = receiver.isImplicitThis();
-		constant = FieldReference.getConstantFor(binding, this, isImplicitThisRcv, scope);
+		constant = FieldReference.getConstantFor(fieldBinding, this, isImplicitThisRcv, scope);
 		if (!isImplicitThisRcv) {
 			constant = NotAConstant;
 		}
-		if (binding.isStatic()) {
+		if (fieldBinding.isStatic()) {
 			// static field accessed through receiver? legal but unoptimal (optional warning)
 			if (!(isImplicitThisRcv
 					|| (receiver instanceof NameReference 
 						&& (((NameReference) receiver).bits & Binding.TYPE) != 0))) {
-				scope.problemReporter().nonStaticAccessToStaticField(this, binding);
+				scope.problemReporter().nonStaticAccessToStaticField(this, fieldBinding);
 			}
-			if (!isImplicitThisRcv && binding.declaringClass != receiverType) {
-				scope.problemReporter().indirectAccessToStaticField(this, binding);
+			if (!isImplicitThisRcv && fieldBinding.declaringClass != receiverType) {
+				scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
 			}
 		}
-		return this.resolvedType = binding.type;
+		// perform capture conversion if read access
+		return this.resolvedType = 
+			(((this.bits & IsStrictlyAssignedMASK) == 0) 
+				? fieldBinding.type.capture()
+				: fieldBinding.type);
 	}
 
 	public void setActualReceiverType(ReferenceBinding receiverType) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java
index 0fa1908..6a5a39e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index ad6c97a..5ca6e7d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 6985b7b..0594781 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -180,7 +180,7 @@
 			case GENERIC_ITERABLE :
 				collection.generateCode(scope, codeStream, true);
 				// declaringClass.iterator();
-				final TypeBinding collectionTypeBinding = collection.resolvedType;
+				final TypeBinding collectionTypeBinding = collection.resolvedType.erasure();
 				MethodBinding iteratorMethodBinding =
 					new MethodBinding(
 							AccPublic,
@@ -244,6 +244,19 @@
 					currentScope,
 					this.postCollectionInitStateIndex);
 			}
+		} else {
+			// if unused variable, some side effects still need to be performed (86487)
+			switch(this.kind) {
+				case ARRAY :
+					break;
+				case RAW_ITERABLE :
+				case GENERIC_ITERABLE :
+					// still advance in iterator to prevent infinite loop
+					codeStream.load(this.indexVariable);
+					codeStream.invokeJavaUtilIteratorNext();
+					codeStream.pop();
+					break;
+			}
 		}
 		this.action.generateCode(scope, codeStream);
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
index 223a9ed..98498fb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -163,7 +163,7 @@
 				this.thenStatement.branchChainTo(endifLabel);
 				int position = codeStream.position;
 				codeStream.goto_(endifLabel);
-				codeStream.updateLastRecordedEndPC(position);
+				codeStream.updateLastRecordedEndPC((this.thenStatement instanceof Block) ? ((Block) this.thenStatement).scope : currentScope, position);
 				//goto is tagged as part of the thenAction block
 			}
 			falseLabel.place();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImplicitDocTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImplicitDocTypeReference.java
deleted file mode 100644
index 546e57c..0000000
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImplicitDocTypeReference.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.ast;
-
-import org.eclipse.jdt.internal.compiler.ASTVisitor;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
-public class ImplicitDocTypeReference extends TypeReference {
-	
-	public char[] token;
-
-	public ImplicitDocTypeReference(char[] name, int pos) {
-		super();
-		this.token = name;
-		this.sourceStart = pos;
-		this.sourceEnd = pos;
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
-	 */
-	public TypeReference copyDims(int dim) {
-		return null;
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
-	 */
-	protected TypeBinding getTypeBinding(Scope scope) {
-		this.constant = NotAConstant;
-		return this.resolvedType = scope.enclosingSourceType();
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeName()
-	 */
-	public char[][] getTypeName() {
-		if (this.token != null) {
-			char[][] tokens = { this.token };
-			return tokens;
-		}
-		return null;
-	}
-	public boolean isThis() {
-		return true;
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
-	 */
-	public void traverse(ASTVisitor visitor, BlockScope classScope) {
-		// Do nothing
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
-	 */
-	public void traverse(ASTVisitor visitor, ClassScope classScope) {
-		// Do nothing
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#printExpression(int, java.lang.StringBuffer)
-	 */
-	public StringBuffer printExpression(int indent, StringBuffer output) {
-		return new StringBuffer();
-	}
-}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
index fca4408..d73daf0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
index 987149f..529ae65 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
index 5a47db8..8f4c949 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -72,12 +72,7 @@
 		expression.printExpression(indent, output).append(" instanceof "); //$NON-NLS-1$
 		return type.print(0, output);
 	}
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#reportIllegalCast(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
-	 */
-	public void reportIllegalCast(Scope scope, TypeBinding castType, TypeBinding expressionType) {
-		scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-	}
+
 	public TypeBinding resolveType(BlockScope scope) {
 
 		constant = NotAConstant;
@@ -89,7 +84,10 @@
 		if (checkedType.isTypeVariable() || checkedType.isBoundParameterizedType() || checkedType.isGenericType()) {
 			scope.problemReporter().illegalInstanceOfGenericType(checkedType, this);
 		} else {
-			checkCastTypesCompatibility(scope, checkedType, expressionType, null);
+			boolean isLegal = checkCastTypesCompatibility(scope, checkedType, expressionType, null);
+			if (!isLegal) {
+				scope.problemReporter().notCompatibleTypesError(this, expressionType, checkedType);
+			}
 		}
 		return this.resolvedType = BooleanBinding;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteral.java
index 0e7821e..239145a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
index 9700282..e9cb37b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index 03cdba4..407c27f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,7 +25,7 @@
 	public TypeReference[] exceptionReferences; // @throws, @exception
 	public JavadocReturnStatement returnStatement; // @return
 	public Expression[] seeReferences; // @see
-	public boolean inherited = false;
+	public long inheritedPositions = -1;
 	// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
 	// Store param references for tag with invalid syntax
 	public JavadocSingleNameReference[] invalidParameters; // @param
@@ -124,7 +124,7 @@
 		
 		// get method declaration
 		AbstractMethodDeclaration methDecl = methScope.referenceMethod();
-		boolean overriding = methDecl == null ? false : (methDecl.binding.modifiers & (AccImplementing | AccOverriding)) != 0;
+		boolean overriding = methDecl == null || methDecl.binding == null ? false : !methDecl.binding.isStatic() && ((methDecl.binding.modifiers & (AccImplementing | AccOverriding)) != 0);
 
 		// @see tags
 		int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length;
@@ -175,7 +175,12 @@
 		}
 		
 		// Store if a reference exists to an overriden method/constructor or the method is in a local type,
-		boolean reportMissing = methDecl == null || !((overriding && this.inherited) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType()));
+		boolean reportMissing = methDecl == null || !((overriding && this.inheritedPositions != -1) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType()));
+		if (!overriding && this.inheritedPositions != -1) {
+			int start = (int) (this.inheritedPositions >>> 32);
+			int end = (int) this.inheritedPositions;
+			methScope.problemReporter().javadocUnexpectedTag(start, end);
+		}
 
 		// @param tags
 		resolveParamTags(methScope, reportMissing);
@@ -482,6 +487,7 @@
 				TypeBinding typeBinding = typeRef.resolvedType;
 
 				if (typeBinding != null && typeBinding.isValidBinding() && typeBinding.isClass()) {
+					// accept only valid class binding
 					typeReferences[maxRef++] = typeRef;
 				}
 			}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
index 032ebd2..a662865 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,17 +20,17 @@
 	public int tagValue;
 	public boolean superAccess = false;
 	
-	public JavadocAllocationExpression(long pos) {
-		this.sourceStart = (int) (pos >>> 32);
-		this.sourceEnd = (int) pos;
+	public JavadocAllocationExpression(int start, int end) {
+		this.sourceStart = start;
+		this.sourceEnd = end;
 		this.bits |= InsideJavadoc;
 	}
+	public JavadocAllocationExpression(long pos) {
+		this((int) (pos >>> 32), (int) pos);
+	}
 
-	/*
-	 * Resolves type on a Block or Class scope.
-	 */
 	private TypeBinding internalResolveType(Scope scope) {
-
+	
 		// Propagate the type checking to the arguments, and check if the constructor is defined.
 		this.constant = NotAConstant;
 		if (this.type == null) {
@@ -40,9 +40,10 @@
 		} else {
 			this.resolvedType = this.type.resolveType((BlockScope)scope, true /* check bounds*/);
 		}
-
+	
 		// buffering the arguments' types
 		TypeBinding[] argumentTypes = NoParameters;
+		boolean hasTypeVarArgs = false;
 		if (this.arguments != null) {
 			boolean argHasError = false;
 			int length = this.arguments.length;
@@ -56,22 +57,37 @@
 				}
 				if (argumentTypes[i] == null) {
 					argHasError = true;
+				} else if (!hasTypeVarArgs) {
+					hasTypeVarArgs = argumentTypes[i].isTypeVariable();
 				}
 			}
 			if (argHasError) {
 				return null;
 			}
 		}
-
+	
 		// check resolved type
 		if (this.resolvedType == null) {
 			return null;
 		}
+		this.resolvedType = scope.convertToRawType(this.type.resolvedType);
 		this.superAccess = scope.enclosingSourceType().isCompatibleWith(this.resolvedType);
-
+	
 		ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
 		this.binding = scope.getConstructor(allocationType, argumentTypes, this);
 		if (!this.binding.isValidBinding()) {
+			ReferenceBinding enclosingTypeBinding = allocationType;
+			MethodBinding contructorBinding = this.binding;
+			while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
+				enclosingTypeBinding = enclosingTypeBinding.enclosingType();
+				contructorBinding = scope.getConstructor(enclosingTypeBinding, argumentTypes, this);
+			}
+			if (contructorBinding.isValidBinding()) {
+				this.binding = contructorBinding;
+			}
+		}
+		if (!this.binding.isValidBinding()) {
+			// First try to search a method instead
 			MethodBinding methodBinding = scope.getMethod(this.resolvedType, this.resolvedType.sourceName(), argumentTypes, this);
 			if (methodBinding.isValidBinding()) {
 				this.binding = methodBinding;
@@ -82,6 +98,28 @@
 				scope.problemReporter().javadocInvalidConstructor(this, this.binding, scope.getDeclarationModifiers());
 			}
 			return this.resolvedType;
+		} else if (binding.isVarargs()) {
+			int length = argumentTypes.length;
+			if (!(binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
+				MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+				scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
+			}
+		} else if (hasTypeVarArgs) {
+			MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+			scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
+		} else if (this.binding instanceof ParameterizedMethodBinding) {
+			ParameterizedMethodBinding paramMethodBinding = (ParameterizedMethodBinding) this.binding;
+			if (paramMethodBinding.hasSubstitutedParameters()) {
+				int length = argumentTypes.length;
+				for (int i=0; i<length; i++) {
+					if (paramMethodBinding.parameters[i] != argumentTypes[i] &&
+							paramMethodBinding.parameters[i].erasure() != argumentTypes[i].erasure()) {
+						MethodBinding problem = new ProblemMethodBinding(this.binding, this.binding.selector, argumentTypes, ProblemReasons.NotFound);
+						scope.problemReporter().javadocInvalidConstructor(this, problem, scope.getDeclarationModifiers());
+						break;
+					}
+				}
+			}
 		}
 		if (isMethodUseDeprecated(this.binding, scope)) {
 			scope.problemReporter().javadocDeprecatedMethod(this.binding, this, scope.getDeclarationModifiers());
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
index d55372a..0ba6dae 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java
index e2c44c4..65a5a0f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java
index 67cde84..6d39e34 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
index 9277647..d776a53 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
new file mode 100644
index 0000000..606e479
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class JavadocImplicitTypeReference extends TypeReference {
+	
+	public char[] token;
+
+	public JavadocImplicitTypeReference(char[] name, int pos) {
+		super();
+		this.token = name;
+		this.sourceStart = pos;
+		this.sourceEnd = pos;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
+	 */
+	public TypeReference copyDims(int dim) {
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	protected TypeBinding getTypeBinding(Scope scope) {
+		this.constant = NotAConstant;
+		return this.resolvedType = scope.enclosingSourceType();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeName()
+	 */
+	public char[][] getTypeName() {
+		if (this.token != null) {
+			char[][] tokens = { this.token };
+			return tokens;
+		}
+		return null;
+	}
+	public boolean isThis() {
+		return true;
+	}
+
+	/*
+	 * Resolves type on a Block or Class scope.
+	 */
+	private TypeBinding internalResolveType(Scope scope) {
+		// handle the error here
+		this.constant = NotAConstant;
+		if (this.resolvedType != null) // is a shared type reference which was already resolved
+			return this.resolvedType.isValidBinding() ? this.resolvedType : null; // already reported error
+
+		this.resolvedType = scope.enclosingSourceType();
+		if (this.resolvedType == null)
+			return null; // detected cycle while resolving hierarchy	
+		if (!this.resolvedType.isValidBinding()) {
+			reportInvalidType(scope);
+			return null;
+		}
+		if (isTypeUseDeprecated(this.resolvedType, scope))
+			reportDeprecatedType(scope);
+		return this.resolvedType;
+	}
+
+	/* (non-Javadoc)
+	 * Override super implementation to avoid raw type creation.
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#resolveType(org.eclipse.jdt.internal.compiler.lookup.BlockScope, boolean)
+	 */
+	public TypeBinding resolveType(BlockScope blockScope, boolean checkBounds) {
+		return internalResolveType(blockScope);
+	}
+
+	/* (non-Javadoc)
+	 * Override super implementation to avoid raw type creation.
+	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#resolveType(org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public TypeBinding resolveType(ClassScope classScope) {
+		return internalResolveType(classScope);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.BlockScope)
+	 */
+	public void traverse(ASTVisitor visitor, BlockScope classScope) {
+		// Do nothing
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#traverse(org.eclipse.jdt.internal.compiler.ASTVisitor, org.eclipse.jdt.internal.compiler.lookup.ClassScope)
+	 */
+	public void traverse(ASTVisitor visitor, ClassScope classScope) {
+		// Do nothing
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		return new StringBuffer();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImportReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImportReference.java
index 2f6d5b0..c3fc95b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImportReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImportReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
index 3d10d73..278a6fa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
@@ -1,15 +1,16 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
+import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 
@@ -48,7 +49,9 @@
 		}
 
 		// will check for null after args are resolved
+		
 		TypeBinding[] argumentTypes = NoParameters;
+		boolean hasArgsTypeVar = false;
 		if (this.arguments != null) {
 			boolean argHasError = false; // typeChecks all arguments 
 			int length = this.arguments.length;
@@ -62,6 +65,8 @@
 				}
 				if (argumentTypes[i] == null) {
 					argHasError = true;
+				} else if (!hasArgsTypeVar) {
+					hasArgsTypeVar = argumentTypes[i].isTypeVariable();
 				}
 			}
 			if (argHasError) {
@@ -73,6 +78,7 @@
 		if (this.actualReceiverType == null) {
 			return null;
 		}
+		this.actualReceiverType = scope.convertToRawType(this.receiver.resolvedType);
 		this.superAccess = scope.enclosingSourceType().isCompatibleWith(this.actualReceiverType);
 
 		// base type cannot receive any message
@@ -80,9 +86,32 @@
 			scope.problemReporter().javadocErrorNoMethodFor(this, this.actualReceiverType, argumentTypes, scope.getDeclarationModifiers());
 			return null;
 		}
-		this.binding = (this.receiver != null && this.receiver.isThis())
-			? scope.getImplicitMethod(this.selector, argumentTypes, this)
-			: scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
+		this.binding = scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
+		if (!this.binding.isValidBinding()) {
+			// Try method in enclosing types
+			TypeBinding enclosingTypeBinding = this.actualReceiverType;
+			MethodBinding methodBinding = this.binding;
+			while (!methodBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
+				enclosingTypeBinding = enclosingTypeBinding.enclosingType();
+				methodBinding = scope.getMethod(enclosingTypeBinding, this.selector, argumentTypes, this);
+			}
+			if (methodBinding.isValidBinding()) {
+				this.binding = methodBinding;
+			} else {
+				// Try to search a constructor instead
+				enclosingTypeBinding = this.actualReceiverType;
+				MethodBinding contructorBinding = this.binding;
+				while (!contructorBinding.isValidBinding() && (enclosingTypeBinding.isMemberType() || enclosingTypeBinding.isLocalType())) {
+					enclosingTypeBinding = enclosingTypeBinding.enclosingType();
+					if (CharOperation.equals(this.selector, enclosingTypeBinding.shortReadableName())) {
+						contructorBinding = scope.getConstructor((ReferenceBinding)enclosingTypeBinding, argumentTypes, this);
+					}
+				}
+				if (contructorBinding.isValidBinding()) {
+					this.binding = contructorBinding;
+				}
+			}
+		}
 		if (!this.binding.isValidBinding()) {
 			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
 			switch (this.binding.problemId()) {
@@ -111,6 +140,28 @@
 				if (closestMatch != null) this.binding = closestMatch;
 			}
 			return this.resolvedType = this.binding == null ? null : this.binding.returnType;
+		} else if (hasArgsTypeVar) {
+			MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+			scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
+		} else if (binding.isVarargs()) {
+			int length = argumentTypes.length;
+			if (!(binding.parameters.length == length && argumentTypes[length-1].isArrayType())) {
+				MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+				scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
+			}
+		} else if (this.binding instanceof ParameterizedMethodBinding && this.actualReceiverType instanceof ReferenceBinding) {
+			ParameterizedMethodBinding paramMethodBinding = (ParameterizedMethodBinding) this.binding;
+			if (paramMethodBinding.hasSubstitutedParameters()) {
+				int length = argumentTypes.length;
+				for (int i=0; i<length; i++) {
+					if (paramMethodBinding.parameters[i] != argumentTypes[i] &&
+							paramMethodBinding.parameters[i].erasure() != argumentTypes[i].erasure()) {
+						MethodBinding problem = new ProblemMethodBinding(this.binding, this.selector, argumentTypes, ProblemReasons.NotFound);
+						scope.problemReporter().javadocInvalidMethod(this, problem, scope.getDeclarationModifiers());
+						break;
+					}
+				}
+			}
 		}
 		if (isMethodUseDeprecated(this.binding, scope)) {
 			scope.problemReporter().javadocDeprecatedMethod(this.binding, this, scope.getDeclarationModifiers());
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
index 5daff1e..0122c16 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java
@@ -1,23 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-
+import org.eclipse.jdt.internal.compiler.lookup.*;
 
 
 public class JavadocQualifiedTypeReference extends QualifiedTypeReference {
@@ -33,10 +27,10 @@
 	}
 
 	protected void reportInvalidType(Scope scope) {
-		scope.problemReporter().javadocInvalidType(this, this.resolvedType, scope.getDeclarationModifiers());
+		scope.problemReporter().javadocInvalidType(this, resolvedType, scope.getDeclarationModifiers());
 	}
 	protected void reportDeprecatedType(Scope scope) {
-		scope.problemReporter().javadocDeprecatedType(this.resolvedType, this, scope.getDeclarationModifiers());
+		scope.problemReporter().javadocDeprecatedType(resolvedType, this, scope.getDeclarationModifiers());
 	}
 
 	/* (non-Javadoc)
@@ -57,23 +51,26 @@
 	 */
 	private TypeBinding internalResolveType(Scope scope, boolean checkBounds) {
 		// handle the error here
-		this.constant = NotAConstant;
-		if (this.resolvedType != null) // is a shared type reference which was already resolved
-			return this.resolvedType.isValidBinding() ? this.resolvedType : null; // already reported error
+		constant = NotAConstant;
+		if (resolvedType != null) // is a shared type reference which was already resolved
+			return resolvedType.isValidBinding() ? resolvedType : null; // already reported error
 
-		this.resolvedType = getTypeBinding(scope);
-		if (!this.resolvedType.isValidBinding()) {
-			Binding binding = scope.getTypeOrPackage(this.tokens);
+		resolvedType = getTypeBinding(scope);
+		if (!resolvedType.isValidBinding()) {
+			Binding binding = scope.getTypeOrPackage(tokens);
 			if (binding instanceof PackageBinding) {
-				this.packageBinding = (PackageBinding) binding;
+				packageBinding = (PackageBinding) binding;
 			} else {
 				reportInvalidType(scope);
 			}
 			return null;
 		}
-		if (isTypeUseDeprecated(this.resolvedType, scope))
+		if (isTypeUseDeprecated(resolvedType, scope))
 			reportDeprecatedType(scope);
-		return this.resolvedType = scope.convertToRawType(this.resolvedType);
+		if (resolvedType instanceof ParameterizedTypeBinding) {
+			resolvedType = ((ParameterizedTypeBinding)resolvedType).type;
+		}
+		return resolvedType;
 	}
 
 	/* (non-Javadoc)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java
index d541e00..b6c3655 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,12 +15,10 @@
 
 
 public class JavadocReturnStatement extends ReturnStatement {
-	public char[] description;
 	public boolean empty = true;
 
-	public JavadocReturnStatement(int s, int e, char[] descr) {
+	public JavadocReturnStatement(int s, int e) {
 		super(null, s, e);
-		this.description = descr;
 		this.bits |= InsideJavadoc;
 	}
 
@@ -48,8 +46,8 @@
 	 */
 	public StringBuffer printStatement(int tab, StringBuffer output) {
 		printIndent(tab, output).append("return"); //$NON-NLS-1$
-		if (description != null )
-			output.append(' ').append(description);
+		if (!this.empty)
+			output.append(' ').append(" <not empty>"); //$NON-NLS-1$
 		return output;
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java
index 4bfe4c6..1615daa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
index 44c3c3c..8e9a9b0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java
@@ -1,22 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.Scope;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.*;
 
 
 public class JavadocSingleTypeReference extends SingleTypeReference {
@@ -71,7 +66,10 @@
 		}
 		if (isTypeUseDeprecated(this.resolvedType, scope))
 			reportDeprecatedType(scope);
-		return this.resolvedType = scope.convertToRawType(this.resolvedType);
+		if (resolvedType instanceof ParameterizedTypeBinding) {
+			resolvedType = ((ParameterizedTypeBinding)resolvedType).type;
+		}
+		return resolvedType;
 	}
 
 	/* (non-Javadoc)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
index b24cde3..fd2032d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
index 32aa623..2276df1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index 57fee6e..210e765 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -207,7 +207,7 @@
 						|| initializationType.isCompatibleWith(variableType)) {
 						this.initialization.computeConversion(scope, variableType, initializationType);
 						if (initializationType.needsUncheckedConversion(variableType)) {
-						    scope.problemReporter().unsafeRawConversion(this.initialization, initializationType, variableType);
+						    scope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, variableType);
 						}						
 					} else if (scope.environment().options.sourceLevel >= JDK1_5 // autoboxing
 									&& (scope.isBoxingCompatibleWith(initializationType, variableType) 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
index 6da299b..63288c0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
index e24da63..de0353d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
index ed9b597..31c3bbf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java
index 65f1bd5..82878a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 /*
  * Created on 2004-03-11
  *
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
index 04d0ee8..4c943da 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,7 +41,7 @@
 		output
 			.append(name)
 			.append(" = "); //$NON-NLS-1$
-		value.print(indent, output);
+		value.print(0, output);
 		return output;
 	}
 	
@@ -76,7 +76,11 @@
 							|| (leafType.isBaseType() && BaseTypeBinding.isWidening(leafType.id, valueType.id)))
 							|| valueType.isCompatibleWith(leafType))) {
 				
-				scope.problemReporter().typeMismatchError(valueType, requiredType, this.value);
+				if (leafType.isAnnotationType() && !valueType.isAnnotationType()) {
+					scope.problemReporter().annotationValueMustBeAnnotation(this.binding.declaringClass, this.name, this.value, leafType);				
+				} else {
+					scope.problemReporter().typeMismatchError(valueType, requiredType, this.value);
+				}
 				return; // may allow to proceed to find more errors at once
 			}
 		} else {
@@ -130,6 +134,9 @@
 				break checkAnnotationMethodType;
 			}
 			if (leafType.isAnnotationType()) {
+				if (!valueType.leafComponentType().isAnnotationType()) { // null literal
+					scope.problemReporter().annotationValueMustBeAnnotation(this.binding.declaringClass, this.name, this.value, leafType);
+				}
 				break checkAnnotationMethodType;
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 05b78da..624b6a6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
@@ -14,6 +14,7 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
@@ -67,7 +68,10 @@
 		if (originalBinding != this.binding) {
 		    // extra cast needed if method return type has type variable
 		    if ((originalBinding.returnType.tagBits & TagBits.HasTypeVariable) != 0 && runtimeTimeType.id != T_JavaLangObject) {
-		        this.valueCast = originalBinding.returnType.genericCast(scope.boxing(runtimeTimeType)); // runtimeType could be base type in boxing case
+		    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 
+		    		? compileTimeType  // unboxing: checkcast before conversion
+		    		: runtimeTimeType;
+		        this.valueCast = originalBinding.returnType.genericCast(targetType); 
 		    }
 		} 	else if (this.actualReceiverType.isArrayType() 
 						&& runtimeTimeType.id != T_JavaLangObject
@@ -101,6 +105,7 @@
 		codeStream.generateOuterAccess(path, this, targetType, currentScope);
 	} else {
 		receiver.generateCode(currentScope, codeStream, !isStatic);
+		codeStream.recordPositionsFrom(pc, this.sourceStart);
 	}
 	// generate arguments
 	generateArguments(binding, arguments, currentScope, codeStream);
@@ -112,7 +117,7 @@
 			if( (receiver.isSuper()) || this.codegenBinding.isPrivate()){
 				codeStream.invokespecial(this.codegenBinding);
 			} else {
-				if ((this.codegenBinding.declaringClass.modifiers & AccInterface) != 0) { // interface or annotation type
+				if (this.codegenBinding.declaringClass.isInterface()) { // interface or annotation type
 					codeStream.invokeinterface(this.codegenBinding);
 				} else {
 					codeStream.invokevirtual(this.codegenBinding);
@@ -198,15 +203,16 @@
 	// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
 	// and not from Object or implicit static method call.	
 	if (this.binding.declaringClass != this.actualReceiverType
-		&& !this.actualReceiverType.isArrayType()
-		&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
-				&& (!receiver.isImplicitThis() || !this.codegenBinding.isStatic())
+			&& !this.actualReceiverType.isArrayType()) {
+		CompilerOptions options = currentScope.environment().options;
+		if ((options.targetJDK >= ClassFileConstants.JDK1_2
+				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
 				&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object methods
-			|| !this.binding.declaringClass.canBeSeenBy(currentScope))) {
+			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
 
-		this.codegenBinding = currentScope.enclosingSourceType().getUpdatedMethodBinding(
-		        										this.codegenBinding, (ReferenceBinding) this.actualReceiverType.erasure());
-
+			this.codegenBinding = currentScope.enclosingSourceType().getUpdatedMethodBinding(
+			        										this.codegenBinding, (ReferenceBinding) this.actualReceiverType.erasure());
+		}
 		// Post 1.4.0 target, array clone() invocations are qualified with array type 
 		// This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding)
 	}
@@ -345,11 +351,14 @@
 			scope.problemReporter().mustUseAStaticMethod(this, binding);
 		} else {
 			// compute generic cast if necessary
-			TypeBinding expectedReceiverType = this.actualReceiverType.erasure().isCompatibleWith(this.binding.declaringClass.erasure())
-				? this.actualReceiverType
-				: this.binding.declaringClass;
-			receiver.computeConversion(scope, expectedReceiverType, actualReceiverType);
-			if (expectedReceiverType != this.actualReceiverType) this.actualReceiverType = expectedReceiverType;
+			TypeBinding receiverErasure = this.actualReceiverType.erasure();
+			if (receiverErasure instanceof ReferenceBinding) {
+				ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo((ReferenceBinding)this.binding.declaringClass.erasure());
+				if (match == null) {
+					this.actualReceiverType = this.binding.declaringClass; // handle indirect inheritance thru variable secondary bound
+				}
+			}
+			receiver.computeConversion(scope, this.actualReceiverType, this.actualReceiverType);
 		}
 	} else {
 		// static message invoked through receiver? legal but unoptimal (optional warning).
@@ -363,8 +372,7 @@
 			scope.problemReporter().indirectAccessToStaticMethod(this, binding);
 		}		
 	}
-	if (this.arguments != null) 
-		checkInvocationArguments(scope, this.receiver, actualReceiverType, binding, this.arguments, argumentTypes, argsContainCast, this);
+	checkInvocationArguments(scope, this.receiver, actualReceiverType, binding, this.arguments, argumentTypes, argsContainCast, this);
 
 	//-------message send that are known to fail at compile time-----------
 	if (binding.isAbstract()) {
@@ -383,7 +391,9 @@
 			&& CharOperation.equals(this.binding.selector, CLONE)) {
 		this.resolvedType = actualReceiverType;
 	} else {
-		this.resolvedType = this.binding.returnType;
+		TypeBinding returnType = this.binding.returnType;
+		if (returnType != null) returnType = returnType.capture();
+		this.resolvedType = returnType;
 	}
 	return this.resolvedType;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
index c9de4c6..6fd8b8d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -133,10 +133,19 @@
 		}
 		
 		// check @Override annotation
-		if (this.binding != null 
-				&& (this.binding.tagBits & TagBits.AnnotationOverride) != 0
-				&& (this.binding.modifiers & AccOverriding) == 0) {
-			scope.problemReporter().methodMustOverride(this);
+		if (this.binding != null) {
+			int bindingModifiers = this.binding.modifiers;
+			if ((this.binding.tagBits & TagBits.AnnotationOverride) != 0 
+					&& (bindingModifiers & AccOverriding) == 0) {
+				// claims to override, and doesn't actually do so
+				scope.problemReporter().methodMustOverride(this);
+			} else	if ((this.binding.tagBits & TagBits.AnnotationOverride) == 0 
+						&& (this.binding.declaringClass.modifiers & AccInterface) == 0
+						&& (bindingModifiers & (AccStatic|AccOverriding)) == AccOverriding
+						&& scope.environment().options.sourceLevel >= JDK1_5) {
+				// actually overrides, but did not claim to do so
+				scope.problemReporter().missingOverrideAnnotation(this);
+			}
 		}
 				
 		// by grammatical construction, interface methods are always abstract
@@ -147,13 +156,13 @@
 			case IGenericType.CLASS_DECL :
 				// if a method has an semicolon body and is not declared as abstract==>error
 				// native methods may have a semicolon body 
-				if ((modifiers & AccSemicolonBody) != 0) {
-					if ((modifiers & AccNative) == 0)
-						if ((modifiers & AccAbstract) == 0)
+				if ((this.modifiers & AccSemicolonBody) != 0) {
+					if ((this.modifiers & AccNative) == 0)
+						if ((this.modifiers & AccAbstract) == 0)
 							scope.problemReporter().methodNeedBody(this);
 				} else {
 					// the method HAS a body --> abstract native modifiers are forbiden
-					if (((modifiers & AccNative) != 0) || ((modifiers & AccAbstract) != 0))
+					if (((this.modifiers & AccNative) != 0) || ((this.modifiers & AccAbstract) != 0))
 						scope.problemReporter().methodNeedingNoBody(this);
 				}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
index c48432f..eb40f09 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java
index d8a720e..db2f90e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java
index ea507f3..88f0d54 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
index 62bea22..9331f30 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
index a544e53..8606d12 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -99,7 +99,7 @@
 				codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex);
 			}			
 			codeStream.generateImplicitConversion(implicitConversion);
-			codeStream.updateLastRecordedEndPC(codeStream.position);
+			codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
 			return;
 		}
@@ -143,17 +143,18 @@
 		if (valueRequired) {
 			if (leftIsConst && leftIsTrue) {
 				codeStream.iconst_1();
-				codeStream.updateLastRecordedEndPC(codeStream.position);
+				codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 			} else {
 				if (rightIsConst && rightIsTrue) {
 					codeStream.iconst_1();
-					codeStream.updateLastRecordedEndPC(codeStream.position);
+					codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 				} else {
 					codeStream.iconst_0();
 				}
 				if (trueLabel.hasForwardReferences()) {
 					if ((bits & ValueForReturnMASK) != 0) {
-						codeStream.ireturn();
+						codeStream.generateImplicitConversion(this.implicitConversion);
+						codeStream.generateReturnBytecode(this);
 						trueLabel.place();
 						codeStream.iconst_1();
 					} else {
@@ -168,7 +169,7 @@
 				}
 			}
 			codeStream.generateImplicitConversion(implicitConversion);
-			codeStream.updateLastRecordedEndPC(codeStream.position);
+			codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 		} else {
 			trueLabel.place();
 		}
@@ -213,7 +214,7 @@
 					// need value, e.g. if (a == 1 || ((b = 2) > 0)) {} -> shouldn't initialize 'b' if a==1
 					if (leftIsConst && leftIsTrue) {
 						codeStream.goto_(trueLabel);
-						codeStream.updateLastRecordedEndPC(codeStream.position);
+						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 						break generateOperands; // no need to generate right operand
 					}
 					if (rightInitStateIndex != -1) {
@@ -223,7 +224,7 @@
 					right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired && !rightIsConst);
 					if (valueRequired && rightIsConst && rightIsTrue) {
 						codeStream.goto_(trueLabel);
-						codeStream.updateLastRecordedEndPC(codeStream.position);
+						codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 					}
 				}
 			} else {
@@ -244,7 +245,7 @@
 					if (valueRequired && rightIsConst) {
 						if (!rightIsTrue) {
 							codeStream.goto_(falseLabel);
-							codeStream.updateLastRecordedEndPC(codeStream.position);
+							codeStream.updateLastRecordedEndPC(currentScope, codeStream.position);
 						}
 					}
 					internalTrueLabel.place();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
index 7ea85eb..8a3d398 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
index c32c609..d9198df 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
index eed5a1f..a2b82dc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -52,7 +52,7 @@
 			TypeBinding[] argTypes = parameterizedType.arguments;
 			if (argTypes != null && typeVariables != null) { // argTypes may be null in error cases
 				for (int i = 0, argLength = typeVariables.length; i < argLength; i++)
-				    if (!typeVariables[i].boundCheck(parameterizedType, argTypes[i]))
+				    if (typeVariables[i].boundCheck(parameterizedType, argTypes[i])  != TypeConstants.OK)
 						scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[index][i]);
 			}
 		}
@@ -166,7 +166,9 @@
 						argTypes[j] = argType;
 					}			    
 				}
-				if (argHasError) return null;
+				if (argHasError) {
+					return null;
+				}
 // TODO (philippe)	if ((this.bits & ASTNode.IsSuperType) != 0)
 				if (isClassScope)
 					if (((ClassScope) scope).detectHierarchyCycle(currentType, this, argTypes))
@@ -186,13 +188,27 @@
 							this, scope.environment().createRawType((ReferenceBinding)currentType.erasure(), qualifiedType), argTypes);
 					typeIsConsistent = false;				
 				}
-				ParameterizedTypeBinding parameterizedType = scope.createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, qualifiedType);
-				// check argument type compatibility
-				if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
-					for (int j = 0; j < argLength; j++)
-					    if (!typeVariables[j].boundCheck(parameterizedType, argTypes[j]))
-							scope.problemReporter().typeMismatchError(argTypes[j], typeVariables[j], currentType, args[j]);
-				qualifiedType = parameterizedType;
+				// if generic type X<T> is referred to as parameterized X<T>, then answer itself
+				boolean isIdentical = (qualifiedType == null) || (qualifiedType instanceof SourceTypeBinding);
+				if (isIdentical) {
+				    for (int j = 0; j < argLength; j++) {
+						if (typeVariables[j] != argTypes[j]) {
+							isIdentical = false;
+						    break;
+						}
+					}
+				}
+			    if (isIdentical) {
+			    	qualifiedType = (ReferenceBinding) currentType.erasure();
+			    } else {
+					ParameterizedTypeBinding parameterizedType = scope.createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, qualifiedType);
+					// check argument type compatibility
+					if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
+						for (int j = 0; j < argLength; j++)
+						    if (typeVariables[j].boundCheck(parameterizedType, argTypes[j]) != TypeConstants.OK)
+								scope.problemReporter().typeMismatchError(argTypes[j], typeVariables[j], currentType, args[j]);
+					qualifiedType = parameterizedType;
+			    }
 		    } else {
 // TODO (philippe)	if ((this.bits & ASTNode.IsSuperType) != 0)
 				if (isClassScope)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
index 8c4494f..587c70a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -38,7 +38,7 @@
 			TypeBinding[] argTypes = parameterizedType.arguments;
 			if (argTypes != null && typeVariables != null) { // may be null in error cases
 				for (int i = 0, argLength = typeVariables.length; i < argLength; i++)
-					if (!typeVariables[i].boundCheck(parameterizedType, argTypes[i]))
+					if (typeVariables[i].boundCheck(parameterizedType, argTypes[i]) != TypeConstants.OK)
 						scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[i]);
 			}
 		}
@@ -106,8 +106,10 @@
 			enclosingType = this.resolvedType.enclosingType(); // if member type
 			if (enclosingType != null) {
 				ReferenceBinding currentType = (ReferenceBinding) this.resolvedType;
-				if (currentType.isStatic() && (enclosingType.isGenericType() || enclosingType.isParameterizedType())) {
-					enclosingType = scope.environment().createRawType((ReferenceBinding)enclosingType.erasure(), enclosingType.enclosingType());
+				if (currentType.isStatic() 
+						|| (enclosingType.isGenericType() 
+								&& enclosingType.outermostEnclosingType() != scope.outerMostClassScope().referenceContext.binding)) {
+					enclosingType = (ReferenceBinding) scope.convertToRawType(enclosingType);
 				}
 			}
 		} else { // resolving member type (relatively to enclosingType)
@@ -150,29 +152,33 @@
 		} else if (argLength != typeVariables.length) { // check arity
 			scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes);
 			return null;
+		} else if (!currentType.isStatic() && enclosingType != null && enclosingType.isRawType()){
+			scope.problemReporter().rawMemberTypeCannotBeParameterized(
+					this, scope.environment().createRawType((ReferenceBinding)currentType.erasure(), enclosingType), argTypes);
+			return null;
 		}
-		// if generic type X<T> is referred to as parameterized X<T>, then answer itself
-		checkGeneric: {
-		    for (int i = 0; i < argLength; i++)
-				if (typeVariables[i] != argTypes[i])
-				    break checkGeneric;
-			return currentType;
-		}
-		ParameterizedTypeBinding parameterizedType = scope.createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, enclosingType);
-		// check argument type compatibility
-		if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
-			for (int i = 0; i < argLength; i++)
-			    if (!typeVariables[i].boundCheck(parameterizedType, argTypes[i]))
-					scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[i]);
 
-		this.resolvedType = parameterizedType;
-		if (isTypeUseDeprecated(this.resolvedType, scope))
-			reportDeprecatedType(scope);
+		// if generic type X<T> is referred to as parameterized X<T>, then answer itself
+		boolean allEqual = true;
+	    for (int i = 0; allEqual && i < argLength; i++)
+			allEqual = typeVariables[i] == argTypes[i];
+	    if (!allEqual) {
+	    	ParameterizedTypeBinding parameterizedType = scope.createParameterizedType((ReferenceBinding)currentType.erasure(), argTypes, enclosingType);
+			// check argument type compatibility
+			if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
+				for (int i = 0; i < argLength; i++)
+				    if (typeVariables[i].boundCheck(parameterizedType, argTypes[i]) != TypeConstants.OK)
+						scope.problemReporter().typeMismatchError(argTypes[i], typeVariables[i], currentType, this.typeArguments[i]);
+	
+			this.resolvedType = parameterizedType;
+			if (isTypeUseDeprecated(this.resolvedType, scope))
+				reportDeprecatedType(scope);
+		}
 		// array type ?
 		if (this.dimensions > 0) {
 			if (dimensions > 255)
 				scope.problemReporter().tooManyDimensions(this);
-			this.resolvedType = scope.createArrayType(parameterizedType, dimensions);
+			this.resolvedType = scope.createArrayType(this.resolvedType, dimensions);
 		}
 		return this.resolvedType;
 	}	
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
index 67f7b4a..f90d202 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
index 1bdb104..1630a0b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
index 289eca2..9e66270 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -162,7 +162,7 @@
 		if (!flowInfo.isReachable()) return;
 		ReferenceBinding allocatedTypeErasure = (ReferenceBinding) binding.declaringClass.erasure();
 
-		// perform some emulation work in case there is some and we are inside a local type only
+		// perform some extra emulation work in case there is some and we are inside a local type only
 		if (allocatedTypeErasure.isNestedType()
 			&& currentScope.enclosingSourceType().isLocalType()) {
 
@@ -231,6 +231,24 @@
 				receiverType = scope.enclosingSourceType();
 			} else {
 				receiverType = this.type.resolveType(scope, true /* check bounds*/);
+				checkParameterizedAllocation: {
+					if (receiverType == null) break checkParameterizedAllocation;
+					if (this.type instanceof ParameterizedQualifiedTypeReference) { // disallow new X<String>.Y<Integer>()
+						ReferenceBinding currentType = (ReferenceBinding)receiverType;
+						do {
+							// isStatic() is answering true for toplevel types
+							if ((currentType.modifiers & AccStatic) != 0) break checkParameterizedAllocation;
+							if (currentType.isRawType()) break checkParameterizedAllocation;
+						} while ((currentType = currentType.enclosingType())!= null);
+						ParameterizedQualifiedTypeReference qRef = (ParameterizedQualifiedTypeReference) this.type;
+						for (int i = qRef.typeArguments.length - 2; i >= 0; i--) {
+							if (qRef.typeArguments[i] != null) {
+								scope.problemReporter().illegalQualifiedParameterizedTypeAllocation(this.type, receiverType);
+								break;
+							}
+						}
+					}
+				}				
 			}			
 		}
 		if (receiverType == null) {
@@ -281,8 +299,7 @@
 				if (isMethodUseDeprecated(binding, scope)) {
 					scope.problemReporter().deprecatedMethod(this.binding, this);
 				}
-				if (this.arguments != null)
-					checkInvocationArguments(scope, null, allocationType, binding, this.arguments, argumentTypes, argsContainCast, this);
+				checkInvocationArguments(scope, null, allocationType, binding, this.arguments, argumentTypes, argsContainCast, this);
 			} else {
 				if (this.binding.declaringClass == null) {
 					this.binding.declaringClass = allocationType;
@@ -307,6 +324,9 @@
 			receiverType = new ProblemReferenceBinding(receiverType.sourceName(), (ReferenceBinding)receiverType, ProblemReasons.IllegalSuperTypeVariable);
 			scope.problemReporter().invalidType(this, receiverType);
 			return null;
+		} else if (type != null && receiverType.isEnum()) { // tolerate enum constant body
+			scope.problemReporter().cannotInstantiate(type, receiverType);
+			return this.resolvedType = receiverType;
 		}
 		// anonymous type scenario
 		// an anonymous class inherits from java.lang.Object when declared "after" an interface
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index 154a32b..2a2905a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -90,10 +90,11 @@
 		}
 		// all intermediate field accesses are read accesses
 		if (otherBindings != null) {
+			boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
 			for (int i = 0; i < otherBindingsCount-1; i++) {
 				lastFieldBinding = otherBindings[i];
 				needValue = !otherBindings[i+1].isStatic();
-				if (needValue) {
+				if (needValue || complyTo14) {
 					manageSyntheticAccessIfNecessary(
 						currentScope, 
 						lastFieldBinding, 
@@ -227,13 +228,22 @@
 			// only for first binding
 		}
 		if (otherBindings != null) {
+			boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
 			for (int i = 0; i < otherBindingsCount; i++) {
 				needValue = i < otherBindingsCount-1 ? !otherBindings[i+1].isStatic() : valueRequired;
-				if (needValue) {
+				if (needValue || complyTo14) {
+					TypeBinding lastReceiverType = getGenericCast(i);
+					if (lastReceiverType == null) {
+						if (i == 0) {
+							 lastReceiverType = ((VariableBinding)binding).type;
+						} else {
+							lastReceiverType = otherBindings[i-1].type;
+						}
+					}
 					manageSyntheticAccessIfNecessary(
 						currentScope, 
 						otherBindings[i], 
-						i == 0 	? ((VariableBinding)binding).type : otherBindings[i-1].type,
+						lastReceiverType,
 						i + 1,
 						flowInfo);
 				}
@@ -281,7 +291,10 @@
 			if (originalBinding != field) {
 			    // extra cast needed if method return type has type variable
 			    if ((originalBinding.type.tagBits & TagBits.HasTypeVariable) != 0 && runtimeTimeType.id != T_JavaLangObject) {
-			    	setGenericCast(length,originalBinding.type.genericCast(scope.boxing(runtimeTimeType))); // runtimeType could be base type in boxing case
+			    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 
+			    		? compileTimeType  // unboxing: checkcast before conversion
+			    		: runtimeTimeType;
+			    	setGenericCast(length,originalBinding.type.genericCast(targetType));
 			    }
 			} 	
 		}
@@ -294,7 +307,9 @@
 		Assignment assignment,
 		boolean valueRequired) {
 			
+		int pc = codeStream.position;
 		FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
+		codeStream.recordPositionsFrom(pc , this.sourceStart);
 		assignment.expression.generateCode(currentScope, codeStream, true);
 		fieldStore(codeStream, lastFieldBinding, syntheticWriteAccessor, valueRequired);
 		// equivalent to valuesRequired[maxOtherBindings]
@@ -313,44 +328,64 @@
 				codeStream.generateConstant(constant, implicitConversion);
 			}
 		} else {
-			FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream); 
-			if (valueRequired) {
-				if (lastFieldBinding.declaringClass == null) { // array length
-					codeStream.arraylength();
-					codeStream.generateImplicitConversion(implicitConversion);
-				} else {
-					if (lastFieldBinding.isConstantValue()) {
-						if (!lastFieldBinding.isStatic()){
-							codeStream.invokeObjectGetClass();
-							codeStream.pop();
-						}
-						// inline the last field constant
+			FieldBinding lastFieldBinding = generateReadSequence(currentScope, codeStream);
+			if (lastFieldBinding != null) {
+				boolean isStatic = lastFieldBinding.isStatic();
+				if (lastFieldBinding.isConstantValue()) {
+					if (!isStatic){
+						codeStream.invokeObjectGetClass();
+						codeStream.pop();
+					}
+					if (valueRequired) { // inline the last field constant
 						codeStream.generateConstant(lastFieldBinding.constant(), implicitConversion);
-					} else {
-						SyntheticMethodBinding accessor =
-							syntheticReadAccessors == null
-								? null
-								: syntheticReadAccessors[syntheticReadAccessors.length - 1];
-						if (accessor == null) {
-							if (lastFieldBinding.isStatic()) {
-								codeStream.getstatic(lastFieldBinding);
+					}
+				} else {
+					if (valueRequired  || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+						if (lastFieldBinding.declaringClass == null) { // array length
+							codeStream.arraylength();
+							if (valueRequired) {
+								codeStream.generateImplicitConversion(implicitConversion);
 							} else {
-								codeStream.getfield(lastFieldBinding);
+								// could occur if !valueRequired but compliance >= 1.4
+								codeStream.pop();
 							}
 						} else {
-							codeStream.invokestatic(accessor);
+							SyntheticMethodBinding accessor =
+								syntheticReadAccessors == null
+									? null
+									: syntheticReadAccessors[syntheticReadAccessors.length - 1];
+							if (accessor == null) {
+								if (isStatic) {
+									codeStream.getstatic(lastFieldBinding);
+								} else {
+									codeStream.getfield(lastFieldBinding);
+								}
+							} else {
+								codeStream.invokestatic(accessor);
+							}
+							TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length);
+							if (valueRequired) {
+								if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
+								codeStream.generateImplicitConversion(implicitConversion);
+							} else {
+								// could occur if !valueRequired but compliance >= 1.4
+								switch (lastFieldBinding.type.id) {
+									case T_long :
+									case T_double :
+										codeStream.pop2();
+										break;
+									default :
+										codeStream.pop();
+								}							
+							}
 						}
-						TypeBinding requiredGenericCast = getGenericCast(this.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length);
-						if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
-						codeStream.generateImplicitConversion(implicitConversion);
-					}
+					} else {
+						if (!isStatic){
+							codeStream.invokeObjectGetClass(); // perform null check
+							codeStream.pop();
+						}
+					}									
 				}
-			} else {
-				if (lastFieldBinding != null && !lastFieldBinding.isStatic()){
-					codeStream.invokeObjectGetClass(); // perform null check
-					codeStream.pop();
-				}
-							
 			}
 		}
 		codeStream.recordPositionsFrom(pc, this.sourceStart);
@@ -472,6 +507,7 @@
 		boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
 		FieldBinding lastFieldBinding = null;
 		TypeBinding lastGenericCast = null;
+		boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
 
 		switch (bits & RestrictiveFlagMASK) {
 			case Binding.FIELD :
@@ -481,7 +517,8 @@
 				if (lastFieldBinding.isConstantValue()) {
 					break;
 				}
-				if (needValue && !lastFieldBinding.isStatic()) {
+				if ((needValue || complyTo14) && !lastFieldBinding.isStatic()) {
+					int pc = codeStream.position;
 					if ((bits & DepthMASK) != 0) {
 						ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT);
 						Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
@@ -489,6 +526,7 @@
 					} else {
 						generateReceiver(codeStream);
 					}
+					codeStream.recordPositionsFrom(pc, this.sourceStart);
 				}
 				break;
 			case Binding.LOCAL : // reading the first local variable
@@ -518,30 +556,37 @@
 				TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
 				if (lastFieldBinding != null) {
 					needValue = !nextField.isStatic();
-					if (needValue) {
-						MethodBinding accessor =
-							syntheticReadAccessors == null ? null : syntheticReadAccessors[i]; 
-						if (accessor == null) {
-							if (lastFieldBinding.isConstantValue()) {
-								if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) {
-									codeStream.invokeObjectGetClass(); // perform null check
-									codeStream.pop();
-								}
-								codeStream.generateConstant(lastFieldBinding.constant(), 0);
-							} else if (lastFieldBinding.isStatic()) {
-								codeStream.getstatic(lastFieldBinding);
-							} else {
-								codeStream.getfield(lastFieldBinding);
-							}
-						} else {
-							codeStream.invokestatic(accessor);
-						}
-						if (lastGenericCast != null) codeStream.checkcast(lastGenericCast);
-					} else {
-						if (this.codegenBinding != lastFieldBinding && !lastFieldBinding.isStatic()){
+					if (lastFieldBinding.isConstantValue()) {
+						if (lastFieldBinding != this.codegenBinding && !lastFieldBinding.isStatic()) {
 							codeStream.invokeObjectGetClass(); // perform null check
 							codeStream.pop();
-						}						
+						}
+						if (needValue) {
+							codeStream.generateConstant(lastFieldBinding.constant(), 0);
+						}
+					} else {
+						if (needValue || complyTo14) {
+							MethodBinding accessor = syntheticReadAccessors == null ? null : syntheticReadAccessors[i]; 
+							if (accessor == null) {
+								if (lastFieldBinding.isStatic()) {
+									codeStream.getstatic(lastFieldBinding);
+								} else {
+									codeStream.getfield(lastFieldBinding);
+								}
+							} else {
+								codeStream.invokestatic(accessor);
+							}
+							if (needValue) {
+								if (lastGenericCast != null) codeStream.checkcast(lastGenericCast);
+							} else {
+								codeStream.pop();
+							}
+						} else {
+							if (this.codegenBinding != lastFieldBinding && !lastFieldBinding.isStatic()){
+								codeStream.invokeObjectGetClass(); // perform null check
+								codeStream.pop();
+							}						
+						}
 					}
 				}
 				lastFieldBinding = nextField;
@@ -610,7 +655,10 @@
 		int index = indexOfFirstFieldBinding;
 		if (index == length) { //	restrictiveFlag == FIELD
 			this.constant = FieldReference.getConstantFor((FieldBinding) binding, this, false, scope);
-			return type;
+			// perform capture conversion if read access
+			return (type != null && (this.bits & IsStrictlyAssignedMASK) == 0)
+					? type.capture()
+					: type;
 		}
 		// allocation of the fieldBindings array	and its respective constants
 		int otherBindingsLength = length - index;
@@ -629,22 +677,28 @@
 			if (type == null)
 				return null; // could not resolve type prior to this point
 
-			// set generic cast of for previous field (if any)
-			if (field != null) {
-				FieldBinding originalBinding = field.original();
-				if (originalBinding != field) {
-				    // extra cast needed if method return type has type variable
-				    if ((originalBinding.type.tagBits & TagBits.HasTypeVariable) != 0 && type.id != T_JavaLangObject) {
-				    	setGenericCast(index-1,originalBinding.type.genericCast(type)); // type cannot be base-type even in boxing case
-				    }
-				} 	
-			}
-			bits &= ~DepthMASK; // flush previous depth if any			
-			field = scope.getField(type, token, this);
+			bits &= ~DepthMASK; // flush previous depth if any		
+			FieldBinding previousField = field;
+			field = scope.getField(type.capture(), token, this);
 			int place = index - indexOfFirstFieldBinding;
 			otherBindings[place] = field;
 			otherDepths[place] = (bits & DepthMASK) >> DepthSHIFT;
 			if (field.isValidBinding()) {
+				// set generic cast of for previous field (if any)
+				if (previousField != null) {
+					TypeBinding fieldReceiverType = type;
+					TypeBinding receiverErasure = type.erasure();
+					if (receiverErasure instanceof ReferenceBinding) {
+						ReferenceBinding match = ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo((ReferenceBinding)field.declaringClass.erasure());
+						if (match == null) {
+							fieldReceiverType = field.declaringClass; // handle indirect inheritance thru variable secondary bound
+						}
+					}				
+					FieldBinding originalBinding = previousField.original();
+				    if ((originalBinding.type.tagBits & TagBits.HasTypeVariable) != 0 && fieldReceiverType.id != T_JavaLangObject) {
+				    	setGenericCast(index-1,originalBinding.type.genericCast(fieldReceiverType)); // type cannot be base-type even in boxing case
+				    }
+			    }
 				// only last field is actually a write access if any
 				if (isFieldUseDeprecated(field, scope, (this.bits & IsStrictlyAssignedMASK) !=0 && index+1 == length)) {
 					scope.problemReporter().deprecatedField(field, this);
@@ -673,7 +727,11 @@
 			}
 		}
 		setDepth(firstDepth);
-		return (otherBindings[otherBindingsLength - 1]).type;
+		type = (otherBindings[otherBindingsLength - 1]).type;
+		// perform capture conversion if read access
+		return (type != null && (this.bits & IsStrictlyAssignedMASK) == 0)
+				? type.capture()
+				: type;		
 	}
 	public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
 		if (!flowInfo.isReachable()) return;
@@ -731,20 +789,24 @@
 		// if the binding declaring class is not visible, need special action
 		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
 		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
+		// and not from Object or implicit static field access.	
 		if (fieldBinding.declaringClass != lastReceiverType
-			&& !lastReceiverType.isArrayType()			
-			&& fieldBinding.declaringClass != null
-			&& !fieldBinding.isConstantValue()
-			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
-					&& (fieldBinding != binding || indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
-					&& fieldBinding.declaringClass.id != T_JavaLangObject)
-				|| !fieldBinding.declaringClass.canBeSeenBy(currentScope))){
+				&& !lastReceiverType.isArrayType()
+				&& fieldBinding.declaringClass != null // array.length
+				&& !fieldBinding.isConstantValue()) {
+			CompilerOptions options = currentScope.environment().options;
+			if ((options.targetJDK >= ClassFileConstants.JDK1_2
+					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || fieldBinding != binding || indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
+					&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
+				|| !fieldBinding.declaringClass.canBeSeenBy(currentScope)) {
+	
 		    setCodegenBinding(
 		            index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index, 
 		            currentScope.enclosingSourceType().getUpdatedFieldBinding(
 		                    getCodegenBinding(index < 0 ? (this.otherBindings == null ? 0 : this.otherBindings.length) : index), 
 		                    (ReferenceBinding)lastReceiverType.erasure()));
-		}
+			}
+		}			
 	}
 
 	public StringBuffer printExpression(int indent, StringBuffer output) {
@@ -798,7 +860,7 @@
 							if ((!fieldBinding.isStatic() || methodScope.isStatic)
 								&& this.indexOfFirstFieldBinding == 1) {
 								scope.problemReporter().forwardReference(this, 0, scope.enclosingSourceType());
-								}
+							}
 						}
 						if (!fieldBinding.isStatic() 
 								&& this.indexOfFirstFieldBinding == 1
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
index 67e95fc..208cf75 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
index 9dcbb4c..58c59a7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
index d3518a0..004b9af 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
index 5a62bb6..cb6e8ed 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,7 +32,7 @@
 	return null ;
 }
 public void fieldStore(CodeStream codeStream, FieldBinding fieldBinding, MethodBinding syntheticWriteAccessor, boolean valueRequired) {
-
+	int pc = codeStream.position;
 	if (fieldBinding.isStatic()) {
 		if (valueRequired) {
 			if ((fieldBinding.type == LongBinding) || (fieldBinding.type == DoubleBinding)) {
@@ -60,6 +60,7 @@
 			codeStream.invokestatic(syntheticWriteAccessor);
 		}
 	}
+	codeStream.recordPositionsFrom(pc, this.sourceStart);
 }
 public abstract void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired);
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 74b3192..ba0a093 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -147,34 +147,9 @@
 	 */
 	public void generateReturnBytecode(CodeStream codeStream) {
 	
-		if (expression == null) {
-			codeStream.return_();
-		} else {
-			final int implicitConversion = expression.implicitConversion;
-			if ((implicitConversion & BOXING) != 0) {
-				codeStream.areturn();
-				return;
-			}
-			int runtimeType = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
-			switch (runtimeType) {
-				case T_boolean :
-				case T_int :
-					codeStream.ireturn();
-					break;
-				case T_float :
-					codeStream.freturn();
-					break;
-				case T_long :
-					codeStream.lreturn();
-					break;
-				case T_double :
-					codeStream.dreturn();
-					break;
-				default :
-					codeStream.areturn();
-			}
-		}
+		codeStream.generateReturnBytecode(this.expression);
 	}
+	
 	public void generateStoreSaveValueIfNecessary(CodeStream codeStream){
 		if (saveValueVariable != null) codeStream.store(saveValueVariable, false);
 	}
@@ -232,7 +207,7 @@
 
 			expression.computeConversion(scope, methodType, expressionType);
 			if (expressionType.needsUncheckedConversion(methodType)) {
-			    scope.problemReporter().unsafeRawConversion(this.expression, expressionType, methodType);
+			    scope.problemReporter().unsafeTypeConversion(this.expression, expressionType, methodType);
 			}
 			return;
 		} else if (scope.isBoxingCompatibleWith(expressionType, methodType)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
index ff9881f..40e5780 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index eb937a6..4bbe1a8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -193,7 +193,10 @@
 			if (originalBinding != this.binding) {
 			    // extra cast needed if method return type has type variable
 			    if ((originalBinding.type.tagBits & TagBits.HasTypeVariable) != 0 && runtimeTimeType.id != T_JavaLangObject) {
-			        this.genericCast = originalBinding.type.genericCast(scope.boxing(runtimeTimeType)); // runtimeType could be base type in boxing case
+			    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 
+			    		? compileTimeType  // unboxing: checkcast before conversion
+			    		: runtimeTimeType;
+			        this.genericCast = originalBinding.type.genericCast(scope.boxing(targetType));
 			    }
 			} 	
 		}
@@ -208,7 +211,7 @@
 			SingleNameReference variableReference;
 			if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == binding)) {
 				// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
-				variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.left.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
+				variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, (operation.bits & OperatorMASK) >> OperatorSHIFT, operation.implicitConversion, valueRequired);
 				return;
 			}
 			int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT;
@@ -219,13 +222,14 @@
 				&& (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) // exclude string concatenation which would occur backwards
 				&& (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { // exclude string concatenation which would occur backwards
 				// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
-				variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.right.implicitConversion /*should be equivalent to no conversion*/, valueRequired);
+				variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.implicitConversion, valueRequired);
 				return;
 			}
 		}
 		switch (bits & RestrictiveFlagMASK) {
 			case Binding.FIELD : // assigning to a field
 				FieldBinding fieldBinding;
+				int pc = codeStream.position;
 				if (!(fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { // need a receiver?
 					if ((bits & DepthMASK) != 0) {
 						ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT);
@@ -235,6 +239,7 @@
 						this.generateReceiver(codeStream);
 					}
 				}
+				codeStream.recordPositionsFrom(pc, this.sourceStart);
 				assignment.expression.generateCode(currentScope, codeStream, true);
 				fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], valueRequired);
 				if (valueRequired) {
@@ -296,11 +301,16 @@
 		} else {
 			switch (bits & RestrictiveFlagMASK) {
 				case Binding.FIELD : // reading a field
-					FieldBinding fieldBinding;
-					if (valueRequired) {
-						if (!(fieldBinding = (FieldBinding) this.codegenBinding).isConstantValue()) { // directly use inlined value for constant fields
-							boolean isStatic;
-							if (!(isStatic = fieldBinding.isStatic())) {
+					FieldBinding fieldBinding = (FieldBinding) this.codegenBinding;
+					if (fieldBinding.isConstantValue()) {
+						// directly use inlined value for constant fields
+						if (valueRequired) {
+							codeStream.generateConstant(fieldBinding.constant(), implicitConversion);
+						}
+					} else {
+						if (valueRequired || currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+							boolean isStatic = fieldBinding.isStatic();
+							if (!isStatic) {
 								if ((bits & DepthMASK) != 0) {
 									ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT);
 									Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
@@ -319,10 +329,20 @@
 							} else {
 								codeStream.invokestatic(syntheticAccessors[READ]);
 							}
-							if (this.genericCast != null) codeStream.checkcast(this.genericCast);
-							codeStream.generateImplicitConversion(implicitConversion);
-					} else { // directly use the inlined value
-							codeStream.generateConstant(fieldBinding.constant(), implicitConversion);
+							if (valueRequired) {
+								if (this.genericCast != null) codeStream.checkcast(this.genericCast);			
+								codeStream.generateImplicitConversion(implicitConversion);
+							} else {
+								// could occur if !valueRequired but compliance >= 1.4
+								switch (fieldBinding.type.id) {
+									case T_long :
+									case T_double :
+										codeStream.pop2();
+										break;
+									default :
+										codeStream.pop();
+								}
+							}							
 						}
 					}
 					break;
@@ -552,7 +572,6 @@
 	}
 	
 	public void generateReceiver(CodeStream codeStream) {
-		
 		codeStream.aload_0();
 	}
 
@@ -602,18 +621,21 @@
 			// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
 			// and not from Object or implicit static field access.	
 			if (fieldBinding.declaringClass != this.actualReceiverType
-				&& !this.actualReceiverType.isArrayType()	
-				&& fieldBinding.declaringClass != null
-				&& !fieldBinding.isConstantValue()
-				&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2 
-						&& !fieldBinding.isStatic()
-						&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields (if there was any)
-					|| !codegenField.declaringClass.canBeSeenBy(currentScope))){
-				this.codegenBinding = 
-				    currentScope.enclosingSourceType().getUpdatedFieldBinding(
-					       codegenField, 
-					        (ReferenceBinding)this.actualReceiverType.erasure());
-			}
+					&& !this.actualReceiverType.isArrayType()
+					&& fieldBinding.declaringClass != null // array.length
+					&& !fieldBinding.isConstantValue()) {
+				CompilerOptions options = currentScope.environment().options;
+				if ((options.targetJDK >= ClassFileConstants.JDK1_2
+						&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
+						&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
+					|| !fieldBinding.declaringClass.canBeSeenBy(currentScope)) {
+		
+					this.codegenBinding = 
+					    currentScope.enclosingSourceType().getUpdatedFieldBinding(
+						       codegenField, 
+						        (ReferenceBinding)this.actualReceiverType.erasure());
+				}
+			}					
 		}
 	}
 	public StringBuffer printExpression(int indent, StringBuffer output){
@@ -653,22 +675,30 @@
 						if (binding instanceof LocalVariableBinding) {
 							bits &= ~RestrictiveFlagMASK;  // clear bits
 							bits |= Binding.LOCAL;
-							if ((this.bits & IsStrictlyAssignedMASK) == 0) {
-								constant = variable.constant();
-							} else {
-								constant = NotAConstant;
-							}
 							if (!variable.isFinal() && (bits & DepthMASK) != 0) {
 								scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)variable, this);
 							}
-							return this.resolvedType = variable.type;
+							TypeBinding fieldType = variable.type;
+							if ((this.bits & IsStrictlyAssignedMASK) == 0) {
+								constant = variable.constant();
+								if (fieldType != null) 
+									fieldType = fieldType.capture(); // perform capture conversion if read access
+							} else {
+								constant = NotAConstant;
+							}
+							return this.resolvedType = fieldType;
 						}
 						// a field
 						FieldBinding field = (FieldBinding) this.binding;
 						if (!field.isStatic() && scope.environment().options.getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
 							scope.problemReporter().unqualifiedFieldAccess(this, field);
 						}
-						return this.resolvedType = checkFieldAccess(scope);
+						// perform capture conversion if read access
+						TypeBinding fieldType = checkFieldAccess(scope);
+						return this.resolvedType = 
+							(((this.bits & IsStrictlyAssignedMASK) == 0) 
+								? fieldType.capture()
+								: fieldType);
 					}
 	
 					// thus it was a type
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
index 55655f0..a560b5e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 591165d..fe0e0fb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -57,35 +57,44 @@
 			}
 
 			ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type
+			int elementsTypeID = varArgsType.elementsType().id;
 			int argLength = arguments == null ? 0 : arguments.length;
 
-			generateVarargsArgument: {
-				if (argLength >= paramLength) {
-					// right number of arguments - could be inexact - pass argument as is
-					TypeBinding lastType = arguments[varArgIndex].resolvedType;
-					if (lastType == NullBinding || varArgsType.dimensions() == lastType.dimensions()) {
-						// foo(1, new int[]{2, 3}) or foo(1, null) --> last arg is passed as-is
-						arguments[varArgIndex].generateCode(currentScope, codeStream, true);
-						break generateVarargsArgument;
-					}
-					// right number but not directly compatible or too many arguments - wrap extra into array
-					// called with (argLength - lastIndex) elements : foo(1, 2) or foo(1, 2, 3, 4)
-					// need to gen elements into an array, then gen each remaining element into created array
-					codeStream.generateInlinedValue(argLength - varArgIndex);
-					codeStream.newArray(varArgsType); // create a mono-dimensional array
-					int elementsTypeID = varArgsType.elementsType().id;
-					for (int i = varArgIndex; i < argLength; i++) {
-						codeStream.dup();
-						codeStream.generateInlinedValue(i - varArgIndex);
-						arguments[i].generateCode(currentScope, codeStream, true);
-						codeStream.arrayAtPut(elementsTypeID, false);
-					}
-				} else { // not enough arguments - pass extra empty array
-					// scenario: foo(1) --> foo(1, new int[0])
-					// generate code for an empty array of parameterType
-					codeStream.generateInlinedValue(0);
-					codeStream.newArray(varArgsType); // create a mono-dimensional array
+			if (argLength > paramLength) {
+				// right number but not directly compatible or too many arguments - wrap extra into array
+				// called with (argLength - lastIndex) elements : foo(1, 2) or foo(1, 2, 3, 4)
+				// need to gen elements into an array, then gen each remaining element into created array
+				codeStream.generateInlinedValue(argLength - varArgIndex);
+				codeStream.newArray(varArgsType); // create a mono-dimensional array
+				for (int i = varArgIndex; i < argLength; i++) {
+					codeStream.dup();
+					codeStream.generateInlinedValue(i - varArgIndex);
+					arguments[i].generateCode(currentScope, codeStream, true);
+					codeStream.arrayAtPut(elementsTypeID, false);
 				}
+			} else if (argLength == paramLength) {
+				// right number of arguments - could be inexact - pass argument as is
+				TypeBinding lastType = arguments[varArgIndex].resolvedType;
+				if (lastType == NullBinding
+					|| (varArgsType.dimensions() == lastType.dimensions()
+						&& lastType.isCompatibleWith(varArgsType))) {
+					// foo(1, new int[]{2, 3}) or foo(1, null) --> last arg is passed as-is
+					arguments[varArgIndex].generateCode(currentScope, codeStream, true);
+				} else {
+					// right number but not directly compatible or too many arguments - wrap extra into array
+					// need to gen elements into an array, then gen each remaining element into created array
+					codeStream.generateInlinedValue(1);
+					codeStream.newArray(varArgsType); // create a mono-dimensional array
+					codeStream.dup();
+					codeStream.generateInlinedValue(0);
+					arguments[varArgIndex].generateCode(currentScope, codeStream, true);
+					codeStream.arrayAtPut(elementsTypeID, false);
+				}
+			} else { // not enough arguments - pass extra empty array
+				// scenario: foo(1) --> foo(1, new int[0])
+				// generate code for an empty array of parameterType
+				codeStream.generateInlinedValue(0);
+				codeStream.newArray(varArgsType); // create a mono-dimensional array
 			}
 		} else if (arguments != null) { // standard generation for method arguments
 			for (int i = 0, max = arguments.length; i < max; i++)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
index 833b5d5..6264eb5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java
index 1ea7892..61b3486 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java
index 754efdf..4df0bda 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
index 9519a34..88a9c39 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
index 6050f9f..26e4cf1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,8 +14,10 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.flow.*;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
 
 public class SwitchStatement extends Statement {
 
@@ -56,12 +58,12 @@
 				for (int i = 0, max = statements.length; i < max; i++) {
 					Statement statement = statements[i];
 					if ((caseIndex < caseCount) && (statement == cases[caseIndex])) { // statement is a case
-						this.scope.switchCase = cases[caseIndex]; // record entering in a switch case block
+						this.scope.enclosingCase = cases[caseIndex]; // record entering in a switch case block
 						caseIndex++;
 						caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits());
 						didAlreadyComplain = false; // reset complaint
 					} else if (statement == defaultCase) { // statement is the default case
-						this.scope.switchCase = defaultCase; // record entering in a switch case block
+						this.scope.enclosingCase = defaultCase; // record entering in a switch case block
 						caseInits = caseInits.mergedWith(flowInfo.copy().unconditionalInits());
 						didAlreadyComplain = false; // reset complaint
 					}
@@ -89,7 +91,7 @@
 				currentScope.methodScope().recordInitializationStates(mergedInfo);
 			return mergedInfo;
 	    } finally {
-	        if (this.scope != null) this.scope.switchCase = null; // no longer inside switch case block
+	        if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
 	    }
 	}
 
@@ -156,7 +158,7 @@
 				} else {
 					codeStream.lookupswitch(defaultLabel, this.constants, sortedIndexes, caseLabels);
 				}
-				codeStream.updateLastRecordedEndPC(codeStream.position);
+				codeStream.updateLastRecordedEndPC(this.scope, codeStream.position);
 			}
 			
 			// generate the switch block statements
@@ -165,14 +167,14 @@
 				for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) {
 					Statement statement = this.statements[i];
 					if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case
-						this.scope.switchCase = this.cases[caseIndex]; // record entering in a switch case block
+						this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block
 						if (preSwitchInitStateIndex != -1) {
 							codeStream.removeNotDefinitelyAssignedVariables(currentScope, preSwitchInitStateIndex);
 						}
 						caseIndex++;
 					} else {
 						if (statement == this.defaultCase) { // statements[i] is a case or a default case
-							this.scope.switchCase = this.defaultCase; // record entering in a switch case block
+							this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
 							if (preSwitchInitStateIndex != -1) {
 								codeStream.removeNotDefinitelyAssignedVariables(currentScope, preSwitchInitStateIndex);
 							}
@@ -196,7 +198,7 @@
 			}
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
 	    } finally {
-	        if (this.scope != null) this.scope.switchCase = null; // no longer inside switch case block
+	        if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
 	    }		
 	}
 
@@ -221,6 +223,7 @@
 	public void resolve(BlockScope upperScope) {
 	
 	    try {
+			boolean isEnumSwitch = false;
 			TypeBinding expressionType = expression.resolveType(upperScope);
 			if (expressionType == null)
 				return;
@@ -232,6 +235,7 @@
 					if (expressionType.isCompatibleWith(IntBinding))
 						break checkType;
 				} else if (expressionType.isEnum()) {
+					isEnumSwitch = true;
 					break checkType;
 				} else if (upperScope.isBoxingCompatibleWith(expressionType, IntBinding)) {
 					expression.computeConversion(upperScope, IntBinding, expressionType);
@@ -242,7 +246,7 @@
 				return;
 			}
 			if (statements != null) {
-				scope = explicitDeclarations == 0 ? upperScope : new BlockScope(upperScope);
+				scope = /*explicitDeclarations == 0 ? upperScope : */new BlockScope(upperScope);
 				int length;
 				// collection of cases is too big but we will only iterate until caseCount
 				cases = new CaseStatement[length = statements.length];
@@ -291,8 +295,28 @@
 					upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd);
 				}
 			}
+			// for enum switch, check if all constants are accounted for (if no default) 
+			if (isEnumSwitch && defaultCase == null 
+					&& upperScope.environment().options.getSeverity(CompilerOptions.IncompleteEnumSwitch) != ProblemSeverities.Ignore) {
+				int constantCount = this.constants == null ? 0 : this.constants.length; // could be null if no case statement
+				if (constantCount == caseCount // ignore diagnosis if unresolved constants
+						&& caseCount != ((ReferenceBinding)expressionType).enumConstantCount()) {
+					FieldBinding[] enumFields = ((ReferenceBinding)expressionType.erasure()).fields();
+					for (int i = 0, max = enumFields.length; i <max; i++) {
+						FieldBinding enumConstant = enumFields[i];
+						if ((enumConstant.modifiers & AccEnum) == 0) continue;
+						findConstant : {
+							for (int j = 0; j < caseCount; j++) {
+								if (enumConstant.id == this.constants[j]) break findConstant;
+							}
+							// enum constant did not get referenced from switch
+							upperScope.problemReporter().missingEnumConstantCase(this, enumConstant);
+						}
+					}
+				}
+			}
 	    } finally {
-	        if (this.scope != null) this.scope.switchCase = null; // no longer inside switch case block
+	        if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
 	    }
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
index b49d6ad..6f0bf83 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java
index c81c876..0e9cb66 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
index 515d313..c5820ab 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java
index a3bd34d..8258db2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index 9101bce..9431f4a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -250,7 +250,7 @@
 						codeStream.goto_(subRoutineStartLabel);
 						break;
 				}
-				codeStream.updateLastRecordedEndPC(position);
+				codeStream.updateLastRecordedEndPC(tryBlock.scope, position);
 				//goto is tagged as part of the try block
 			}
 			for (int i = 0; i < maxCatches; i++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 580877d..9722d1d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,6 +14,7 @@
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.*;
 import org.eclipse.jdt.internal.compiler.impl.*;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.flow.*;
@@ -372,7 +373,11 @@
 		cd.selector = new char[] { 'x' }; //no maining
 		cd.sourceStart = sourceStart;
 		cd.sourceEnd = sourceEnd;
-		cd.modifiers = modifiers & AccVisibilityMASK;
+		int newModifiers = modifiers & AccVisibilityMASK;
+		if (inheritedConstructorBinding.isVarargs()) {
+			newModifiers |= AccVarargs;
+		}
+		cd.modifiers = newModifiers;
 		cd.isDefaultConstructor = true;
 
 		if (argumentsLength > 0) {
@@ -444,7 +449,7 @@
 	 */
 	public FieldDeclaration declarationOf(FieldBinding fieldBinding) {
 
-		if (fieldBinding != null) {
+		if (fieldBinding != null && this.fields != null) {
 			for (int i = 0, max = this.fields.length; i < max; i++) {
 				FieldDeclaration fieldDecl;
 				if ((fieldDecl = this.fields[i]).binding == fieldBinding)
@@ -459,7 +464,7 @@
 	 */
 	public TypeDeclaration declarationOf(MemberTypeBinding memberTypeBinding) {
 
-		if (memberTypeBinding != null) {
+		if (memberTypeBinding != null && this.memberTypes != null) {
 			for (int i = 0, max = this.memberTypes.length; i < max; i++) {
 				TypeDeclaration memberTypeDecl;
 				if ((memberTypeDecl = this.memberTypes[i]).binding == memberTypeBinding)
@@ -474,7 +479,7 @@
 	 */
 	public AbstractMethodDeclaration declarationOf(MethodBinding methodBinding) {
 
-		if (methodBinding != null) {
+		if (methodBinding != null && this.methods != null) {
 			for (int i = 0, max = this.methods.length; i < max; i++) {
 				AbstractMethodDeclaration methodDecl;
 
@@ -635,6 +640,9 @@
 			for (int i = 0, count = fields.length; i < count; i++) {
 				FieldDeclaration field = fields[i];
 				if (field.isStatic()) {
+					if (!staticFieldInfo.isReachable())
+						field.bits &= ~ASTNode.IsReachableMASK;
+					
 					/*if (field.isField()){
 						staticInitializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
 					} else {*/
@@ -652,6 +660,9 @@
 						staticFieldInfo = FlowInfo.initial(maxFieldCount).setReachMode(FlowInfo.UNREACHABLE);
 					}
 				} else {
+					if (!nonStaticFieldInfo.isReachable())
+						field.bits &= ~ASTNode.IsReachableMASK;
+					
 					/*if (field.isField()){
 						initializerContext.handledExceptions = NoExceptions; // no exception is allowed jls8.3.2
 					} else {*/
@@ -705,13 +716,16 @@
 	}
 
 	public int kind() {
-		if ((modifiers & AccInterface) != 0) {
-			if ((modifiers & AccAnnotation) != 0) 
+		switch (modifiers & (AccInterface|AccAnnotation|AccEnum)) {
+			case AccInterface :
+				return IGenericType.INTERFACE_DECL;
+			case AccInterface|AccAnnotation :
 				return IGenericType.ANNOTATION_TYPE_DECL;
-			return IGenericType.INTERFACE_DECL;
-		} else if ((modifiers & AccEnum) != 0) 
-			return IGenericType.ENUM_DECL;
-		return IGenericType.CLASS_DECL;
+			case AccEnum :
+				return IGenericType.ENUM_DECL;
+			default : 
+				return IGenericType.CLASS_DECL;
+		}
 	}
 	
 	/* 
@@ -724,17 +738,16 @@
 	 */
 	public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
 
-		if (!flowInfo.isReachable()) return;
+ 		if (!flowInfo.isReachable()) return;
 		NestedTypeBinding nestedType = (NestedTypeBinding) binding;
 		
 		MethodScope methodScope = currentScope.methodScope();
 		if (!methodScope.isStatic && !methodScope.isConstructorCall){
-
-			nestedType.addSyntheticArgumentAndField(binding.enclosingType());	
+			nestedType.addSyntheticArgumentAndField(nestedType.enclosingType());	
 		}
 		// add superclass enclosing instance arg for anonymous types (if necessary)
-		if (binding.isAnonymousType()) { 
-			ReferenceBinding superclassBinding = (ReferenceBinding)binding.superclass.erasure();
+		if (nestedType.isAnonymousType()) {
+			ReferenceBinding superclassBinding = (ReferenceBinding)nestedType.superclass.erasure();
 			if (superclassBinding.enclosingType() != null && !superclassBinding.isStatic()) {
 				if (!superclassBinding.isLocalType()
 						|| ((NestedTypeBinding)superclassBinding).getSyntheticField(superclassBinding.enclosingType(), true) != null){
@@ -742,6 +755,27 @@
 					nestedType.addSyntheticArgument(superclassBinding.enclosingType());	
 				}
 			}
+			// From 1.5 on, provide access to enclosing instance synthetic constructor argument when declared inside constructor call
+			// only for direct anonymous type
+			//public class X {
+			//	void foo() {}
+			//	class M {
+			//		M(Object o) {}
+			//		M() { this(new Object() { void baz() { foo(); }}); } // access to #foo() indirects through constructor synthetic arg: val$this$0
+			//	}
+			//}
+			if (!methodScope.isStatic && methodScope.isConstructorCall && currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_5) {
+				ReferenceBinding enclosing = nestedType.enclosingType();
+				if (enclosing.isNestedType()) {
+					NestedTypeBinding nestedEnclosing = (NestedTypeBinding)enclosing;
+//					if (nestedEnclosing.findSuperTypeErasingTo(nestedEnclosing.enclosingType()) == null) { // only if not inheriting
+						SyntheticArgumentBinding syntheticEnclosingInstanceArgument = nestedEnclosing.getSyntheticArgument(nestedEnclosing.enclosingType(), true);
+						if (syntheticEnclosingInstanceArgument != null) {
+							nestedType.addSyntheticArgumentAndField(syntheticEnclosingInstanceArgument);	
+						}
+					}
+//				}
+			}
 		}
 	}
 	
@@ -823,6 +857,9 @@
 
 	public StringBuffer print(int indent, StringBuffer output) {
 
+		if (this.javadoc != null) {
+			this.javadoc.print(indent, output);
+		}
 		if ((this.bits & IsAnonymousTypeMASK) == 0) {
 			printIndent(indent, output);
 			printHeader(0, output);
@@ -925,7 +962,13 @@
 			return;
 		}
 		try {
-			resolveAnnotations(this.staticInitializerScope, this.annotations, sourceType);
+			boolean old = this.staticInitializerScope.insideTypeAnnotation;
+			try {
+				this.staticInitializerScope.insideTypeAnnotation = true;
+				resolveAnnotations(this.staticInitializerScope, this.annotations, sourceType);
+			} finally {
+				this.staticInitializerScope.insideTypeAnnotation = old;
+			}
 			
 			if ((this.bits & UndocumentedEmptyBlockMASK) != 0) {
 				this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd);
@@ -943,6 +986,12 @@
 			int lastVisibleFieldID = -1;
 			boolean hasEnumConstants = false;
 			boolean hasEnumConstantsWithoutBody = false;
+			
+			if (this.typeParameters != null) {
+				for (int i = 0, count = this.typeParameters.length; i < count; i++) {
+					this.typeParameters[i].resolve(this.scope);
+				}
+			}
 			if (this.memberTypes != null) {
 				for (int i = 0, count = this.memberTypes.length; i < count; i++) {
 					this.memberTypes[i].resolve(this.scope);
@@ -997,8 +1046,9 @@
 			if (kind() == IGenericType.ENUM_DECL && this.binding.isAbstract()) {
 				if (!hasEnumConstants || hasEnumConstantsWithoutBody) {
 					for (int i = 0, count = this.methods.length; i < count; i++) {
-						if (this.methods[i].isAbstract()) {
-							this.scope.problemReporter().enumAbstractMethodMustBeImplemented(this.methods[i]);
+						final AbstractMethodDeclaration methodDeclaration = this.methods[i];
+						if (methodDeclaration.isAbstract() && methodDeclaration.binding != null) {
+							this.scope.problemReporter().enumAbstractMethodMustBeImplemented(methodDeclaration);
 						}
 					}
 				}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
index bfa7e3f..4b5511f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,6 +12,7 @@
 
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
@@ -42,7 +43,14 @@
 	}
 	
 	public void resolve(ClassScope scope) {
-	    // TODO (philippe) add warning for detecting variable name collisions
+	    // detect variable/type name collisions
+		if (this.binding != null) {
+			Scope outerScope = scope.parent;
+			Binding existingType = outerScope.getBinding(this.name, Binding.TYPE, this, false);
+			if (existingType != null && this.binding != existingType && existingType.isValidBinding()) {
+				scope.problemReporter().typeHiding(this, existingType);
+			}
+		}
 	}
 
 	/* (non-Javadoc)
@@ -96,4 +104,4 @@
 		}
 		visitor.endVisit(this, scope);
 	}	
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
index 5865269..2f9f08e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
index 7e38c26..dc81aa9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
index fc7be36..4bc538e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
index 8c99f7d..bfa42f7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -64,7 +64,7 @@
 				return null;
 			}	    
 		}
-	    WildcardBinding wildcard = scope.environment().createWildcard(genericType, rank, boundType, this.kind);
+	    WildcardBinding wildcard = scope.environment().createWildcard(genericType, rank, boundType, null /*no extra bound*/, this.kind);
 	    return this.resolvedType = wildcard;
 	}
 	
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
index 57b09e0..eca12de 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
index 20897c2..3d13e57 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,14 +14,13 @@
 import java.io.IOException;
 import java.util.Arrays;
 
-import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
 import org.eclipse.jdt.internal.compiler.env.*;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
@@ -314,53 +313,45 @@
 	int readOffset = offset;
 	int utf8Offset = this.constantPoolOffsets[u2At(offset)];
 	char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	typeName = Signature.toCharArray(typeName);
-	CharOperation.replace(typeName, '/', '.');
-	char[][] qualifiedTypeName = CharOperation.splitOn('.', typeName);
 	int numberOfPairs = u2At(offset + 2);
 	readOffset += 4;
-	switch(qualifiedTypeName.length) {
-		case 3 :
-			if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_DEPRECATED)) {
+	switch(typeName.length) {
+		case 21 :
+			if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_INHERITED)) {
+				this.tagBits |= TagBits.AnnotationInherited;
+				return readOffset;		
+			}
+			break;
+		case 22 :
+			if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_DEPRECATED)) {
 				this.tagBits |= TagBits.AnnotationDeprecated;
 				return readOffset;		
 			}
 			break;
-		case 4 :
-			char[] lastPart = qualifiedTypeName[3];
-			if (lastPart.length > 0) {
-				switch(lastPart[0]) {
-					case 'R' :
-						if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION)) {
-							for (int i = 0; i < numberOfPairs; i++) {
-								readOffset += 2;
-								readOffset = decodeElementValueForJavaLangAnnotationRetention(readOffset);
-							}
-							return readOffset;
-						}
-						break;
-					case 'T' :
-						if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_ANNOTATION_TARGET)) {
-							for (int i = 0; i < numberOfPairs; i++) {
-								readOffset += 2;
-								readOffset = decodeElementValueForJavaLangAnnotationTarget(readOffset);
-							}
-							return readOffset;		
-						}
-						break;
-					case 'D' :
-						if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED)) {
-							this.tagBits |= TagBits.AnnotationDocumented;
-							return readOffset;		
-						}
-						break;
-					case 'I' :
-						if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED)) {
-							this.tagBits |= TagBits.AnnotationInherited;
-							return readOffset;		
-						}
+		case 29 :
+			if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_TARGET)) {
+				for (int i = 0; i < numberOfPairs; i++) {
+					readOffset += 2;
+					readOffset = decodeElementValueForJavaLangAnnotationTarget(readOffset);
 				}
+				return readOffset;		
 			}
+			break;
+		case 33 :
+			if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_DOCUMENTED)) {
+				this.tagBits |= TagBits.AnnotationDocumented;
+				return readOffset;		
+			}
+			break;
+		case 32 :
+			if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTION)) {
+				for (int i = 0; i < numberOfPairs; i++) {
+					readOffset += 2;
+					readOffset = decodeElementValueForJavaLangAnnotationRetention(readOffset);
+				}
+				return readOffset;
+			}
+			break;
 	}
 	for (int i = 0; i < numberOfPairs; i++) {
 		readOffset += 2;
@@ -422,14 +413,11 @@
 		case 'e' :
 			int utf8Offset = this.constantPoolOffsets[u2At(readOffset)];
 			char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-			typeName = Signature.toCharArray(typeName);
-			CharOperation.replace(typeName, '/', '.');
-			char[][] qualifiedTypeName = CharOperation.splitOn('.', typeName);
 			readOffset += 2;
 			utf8Offset = this.constantPoolOffsets[u2At(readOffset)];
 			char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
 			readOffset += 2;
-			if (qualifiedTypeName.length == 4 && CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE)) {
+			if (typeName.length == 34 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_ELEMENTTYPE)) {
 				this.tagBits |= Annotation.getTargetElementType(constName);
 			}
 			break;
@@ -472,15 +460,12 @@
 		case 'e' :
 			int utf8Offset = this.constantPoolOffsets[u2At(readOffset)];
 			char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-			typeName = Signature.toCharArray(typeName);
-			CharOperation.replace(typeName, '/', '.');
-			char[][] qualifiedTypeName = CharOperation.splitOn('.', typeName);
 			readOffset += 2;
 			utf8Offset = this.constantPoolOffsets[u2At(readOffset)];
 			char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
 			readOffset += 2;
 			this.tagBits |= Annotation.getRetentionPolicy(constName);
-			if (qualifiedTypeName.length == 4 && CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY)) {
+			if (typeName.length == 38 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTIONPOLICY)) {
 				this.tagBits |= Annotation.getRetentionPolicy(constName);
 			}
 			break;
@@ -598,13 +583,17 @@
  * @see org.eclipse.jdt.internal.compiler.env.IGenericType#getKind()
  */
 public int getKind() {
-	int modifiers = getModifiers();
-	if ((modifiers & AccInterface) != 0) {
-		if ((modifiers & AccAnnotation) != 0) return IGenericType.ANNOTATION_TYPE_DECL;
-		return IGenericType.INTERFACE_DECL;
-	}
-	if ((modifiers & AccEnum) != 0)	return IGenericType.ENUM_DECL;
-	return IGenericType.CLASS_DECL;
+	
+		switch (getModifiers() & (AccInterface|AccAnnotation|AccEnum)) {
+			case AccInterface :
+				return IGenericType.INTERFACE_DECL;
+			case AccInterface|AccAnnotation :
+				return IGenericType.ANNOTATION_TYPE_DECL;
+			case AccEnum :
+				return IGenericType.ENUM_DECL;
+			default : 
+				return IGenericType.CLASS_DECL;
+		}
 }
 /**
  * Answer the receiver's nested types or null if the array is empty.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
index caaaa17..41b01e6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
index 019ff5e..e8261f8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java
@@ -1,11 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Common Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors: IBM Corporation - initial API and implementation
- ******************************************************************************/
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.classfmt;
 import java.io.PrintStream;
 import java.io.PrintWriter;
@@ -128,4 +130,4 @@
 			}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
index b986492..23c238f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java
@@ -1,18 +1,18 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.classfmt;
 
-import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
 import org.eclipse.jdt.internal.compiler.env.IBinaryField;
 import org.eclipse.jdt.internal.compiler.impl.BooleanConstant;
 import org.eclipse.jdt.internal.compiler.impl.ByteConstant;
@@ -25,7 +25,6 @@
 import org.eclipse.jdt.internal.compiler.impl.ShortConstant;
 import org.eclipse.jdt.internal.compiler.impl.StringConstant;
 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
@@ -84,19 +83,11 @@
 	int readOffset = offset;
 	int utf8Offset = this.constantPoolOffsets[u2At(offset)] - structOffset;
 	char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	typeName = Signature.toCharArray(typeName);
-	CharOperation.replace(typeName, '/', '.');
-	char[][] qualifiedTypeName = CharOperation.splitOn('.', typeName);
 	int numberOfPairs = u2At(offset + 2);
 	readOffset += 4;
-	if (qualifiedTypeName.length == 3) {
-		char[] lastPart = qualifiedTypeName[2];
-		if (lastPart[0] == 'D') {
-			if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_DEPRECATED)) {
-				this.tagBits |= TagBits.AnnotationDeprecated;
-				return readOffset;		
-			}
-		}
+	if (typeName.length == 22 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_DEPRECATED)) {
+		this.tagBits |= TagBits.AnnotationDeprecated;
+		return readOffset;		
 	}
 	for (int i = 0; i < numberOfPairs; i++) {
 		readOffset += 2;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java
index 476c664..98174cb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
index 7a27b96..54c4829 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java
@@ -1,21 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.classfmt;
 
-import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
+import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
 import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
-import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 
 public class MethodInfo extends ClassFileStruct implements IBinaryMethod, AttributeNamesConstants, Comparable {
 	static private final char[][] noException = CharOperation.NO_CHAR_CHAR;
@@ -76,19 +75,11 @@
 	int readOffset = offset;
 	int utf8Offset = this.constantPoolOffsets[u2At(offset)] - structOffset;
 	char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
-	typeName = Signature.toCharArray(typeName);
-	CharOperation.replace(typeName, '/', '.');
-	char[][] qualifiedTypeName = CharOperation.splitOn('.', typeName);
 	int numberOfPairs = u2At(offset + 2);
 	readOffset += 4;
-	if (qualifiedTypeName.length == 3) {
-		char[] lastPart = qualifiedTypeName[2];
-		if (lastPart[0] == 'D') {
-			if (CharOperation.equals(qualifiedTypeName, TypeConstants.JAVA_LANG_DEPRECATED)) {
-				this.tagBits |= TagBits.AnnotationDeprecated;
-				return readOffset;		
-			}
-		}
+	if (typeName.length == 22 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_DEPRECATED)) {
+		this.tagBits |= TagBits.AnnotationDeprecated;
+		return readOffset;		
 	}
 	for (int i = 0; i < numberOfPairs; i++) {
 		readOffset += 2;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
index a49ff00..ded0f3c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
index 725588e..bbea0e1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java
index b5f8126..7e74594 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 343c4e6..ca2388c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -898,20 +898,23 @@
 	position++;
 	bCodeStream[classFileOffset++] = OPC_dup2_x2;
 }
-public void exitUserScope(BlockScope blockScope) {
+public void exitUserScope(BlockScope currentScope) {
 	// mark all the scope's locals as loosing their definite assignment
 
 	if (!generateLocalVariableTableAttributes)
 		return;
-	for (int i = 0; i < visibleLocalsCount; i++) {
-		LocalVariableBinding visibleLocal = visibleLocals[i];
-		if ((visibleLocal != null) && (visibleLocal.declaringScope == blockScope)) { 
-			// there maybe some some preserved locals never initialized
-			if (visibleLocal.initializationCount > 0){
-				visibleLocals[i].recordInitializationEndPC(position);
-			}
-			visibleLocals[i] = null; // this variable is no longer visible afterwards
+	while (visibleLocalsCount > 0) {
+		LocalVariableBinding visibleLocal = visibleLocals[this.visibleLocalsCount - 1];
+		if (visibleLocal == null)
+			continue;
+		if (visibleLocal.declaringScope != currentScope) // left currentScope
+			break;
+
+		// there maybe some some preserved locals never initialized
+		if (visibleLocal.initializationCount > 0){
+			visibleLocal.recordInitializationEndPC(position);
 		}
+		visibleLocals[--this.visibleLocalsCount] = null; // this variable is no longer visible afterwards
 	}
 }
 final public void f2d() {
@@ -1723,7 +1726,36 @@
 		}
 	}
 }
-
+public void generateReturnBytecode(Expression expression) {
+	
+	if (expression == null) {
+		this.return_();
+	} else {
+		final int implicitConversion = expression.implicitConversion;
+		if ((implicitConversion & BOXING) != 0) {
+			this.areturn();
+			return;
+		}
+		int runtimeType = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
+		switch (runtimeType) {
+			case T_boolean :
+			case T_int :
+				this.ireturn();
+				break;
+			case T_float :
+				this.freturn();
+				break;
+			case T_long :
+				this.lreturn();
+				break;
+			case T_double :
+				this.dreturn();
+				break;
+			default :
+				this.areturn();
+		}
+	}
+}
 /**
  * The equivalent code performs a string conversion:
  *
@@ -1777,11 +1809,24 @@
 	if ((syntheticArgumentTypes = targetType.syntheticEnclosingInstanceTypes()) != null) {
 
 		ReferenceBinding targetEnclosingType = checkedTargetType.enclosingType();
-		boolean complyTo14 = currentScope.environment().options.complianceLevel >= ClassFileConstants.JDK1_4;
+		long compliance = currentScope.environment().options.complianceLevel;
+
 		// deny access to enclosing instance argument for allocation and super constructor call (if 1.4)
-		boolean ignoreEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
-					|| (complyTo14 && ((invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess())));
-						
+		// always consider it if complying to 1.5
+		boolean denyEnclosingArgInConstructorCall;
+		if (compliance <= JDK1_3) {
+			denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression;
+		} else if (compliance == JDK1_4){
+			denyEnclosingArgInConstructorCall = invocationSite instanceof AllocationExpression
+				|| invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess();
+		} else {
+			//compliance >= JDK1_5
+			denyEnclosingArgInConstructorCall = (invocationSite instanceof AllocationExpression
+					|| invocationSite instanceof ExplicitConstructorCall && ((ExplicitConstructorCall)invocationSite).isSuperAccess()) 
+				&& !targetType.isLocalType();
+		}
+		
+		boolean complyTo14 = compliance >= ClassFileConstants.JDK1_4;
 		for (int i = 0, max = syntheticArgumentTypes.length; i < max; i++) {
 			ReferenceBinding syntheticArgType = syntheticArgumentTypes[i];
 			if (hasExtraEnclosingInstance && syntheticArgType == targetEnclosingType) {
@@ -1796,7 +1841,7 @@
 				Object[] emulationPath = currentScope.getEmulationPath(
 						syntheticArgType, 
 						false /*not only exact match (that is, allow compatible)*/,
-						ignoreEnclosingArgInConstructorCall);
+						denyEnclosingArgInConstructorCall);
 				this.generateOuterAccess(emulationPath, invocationSite, syntheticArgType, currentScope);
 			}
 		}
@@ -1841,6 +1886,7 @@
 	if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) {
 		this.aload_1(); // pass along name param as name arg
 		this.iload_2(); // pass along ordinal param as ordinal arg
+        resolvedPosition += 2;
 	}	
 	if (declaringClass.isNestedType()) {
 		NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
@@ -2033,7 +2079,7 @@
 			|| accessBinding.kind == SyntheticMethodBinding.SuperMethodAccess){
 			this.invokespecial(methodBinding);
 		} else {
-			if ((methodBinding.declaringClass.modifiers & AccInterface) != 0) { // interface or annotation type
+			if (methodBinding.declaringClass.isInterface()) { // interface or annotation type
 				this.invokeinterface(methodBinding);
 			} else {
 				this.invokevirtual(methodBinding);
@@ -5937,7 +5983,15 @@
 	buffer.append(")"); //$NON-NLS-1$
 	return buffer.toString();
 }
-public void updateLastRecordedEndPC(int pos) {
+/**
+ * Note: it will walk the locals table and extend the end range for all matching ones, no matter if
+ * visible or not.
+ * {  int i = 0;
+ *    {  int j = 1; }
+ * }   <== would process both 'i' and 'j'
+ * Processing non-visible ones is mandated in some cases (include goto instruction after if-then block)
+ */
+public void updateLastRecordedEndPC(Scope scope, int pos) {
 
 	/* Tune positions in the table, this is due to some 
 	 * extra bytecodes being
@@ -5954,21 +6008,18 @@
 		return;
 	this.lastEntryPC = pos;
 	// need to update the initialization endPC in case of generation of local variable attributes.
-	updateLocalVariablesAttribute(pos);
-}
-public void updateLocalVariablesAttribute(int pos) {
-	// need to update the initialization endPC in case of generation of local variable attributes.
-	if (generateLocalVariableTableAttributes) {
-		for (int i = 0, max = locals.length; i < max; i++) {
-			LocalVariableBinding local = locals[i];
-			if ((local != null) && (local.initializationCount > 0)) {
+	if (this.generateLocalVariableTableAttributes) {
+		for (int i = 0, max = this.locals.length; i < max; i++) {
+			LocalVariableBinding local = this.locals[i];
+			if (local != null && local.declaringScope == scope && local.initializationCount > 0) {
 				if (local.initializationPCs[((local.initializationCount - 1) << 1) + 1] == pos) {
-					local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = position;
+					local.initializationPCs[((local.initializationCount - 1) << 1) + 1] = this.position;
 				}
 			}
 		}
 	}
 }
+
 /**
  * Write a signed 16 bits value into the byte array
  * @param value the signed short
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index a4a4509..15fd1bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -233,7 +233,13 @@
 	public static final char[] ValueOfIntSignature = "(I)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
 	public static final char[] ValueOfLongSignature = "(J)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
 	public static final char[] ValueOfObjectSignature = "(Ljava/lang/Object;)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-
+	public static final char[] JAVA_LANG_ANNOTATION_DOCUMENTED = "Ljava/lang/annotation/Documented;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_ELEMENTTYPE = "Ljava/lang/annotation/ElementType;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_RETENTION = "Ljava/lang/annotation/Retention;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_RETENTIONPOLICY = "Ljava/lang/annotation/RetentionPolicy;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_TARGET = "Ljava/lang/annotation/Target;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_DEPRECATED = "Ljava/lang/Deprecated;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVA_LANG_ANNOTATION_INHERITED = "Ljava/lang/Inherited;".toCharArray(); //$NON-NLS-1$
 /**
  * ConstantPool constructor comment.
  */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
index edb7d17..b050f04 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
index 31b2ee5..5f6c807 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FieldNameAndTypeCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FieldNameAndTypeCache.java
index 0982a06..77363c4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FieldNameAndTypeCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FieldNameAndTypeCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
index 3bbe945..9c3e334 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
index 91b36a6..989bdd5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java
index 8c29bce..c286bdc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
index cfb5f08..4f1de1f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MethodNameAndTypeCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MethodNameAndTypeCache.java
index 2ab3da3..96ea259 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MethodNameAndTypeCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MethodNameAndTypeCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
index a1ff0eb..382b9bd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
index 8fc2355..1f222ca 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java
index 1ed5061..9a2dc0a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java
@@ -1,120 +1,35 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.env;
 
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.util.Util;
-
-/**
- * Definition of an access restriction rule used to flag forbidden references to non API code.
- * A restriction can chain to further ones, the first violated restriction taking precedence.
- */
 public class AccessRestriction {
 
-	private char[][] inclusionPatterns;
-	private char[][] exclusionPatterns;
-	protected String messageTemplate;
-	AccessRestriction furtherRestriction; // subsequent restriction
-	
-	
-	public AccessRestriction(String messageTemplate, char[][] inclusionPatterns, char[][] exclusionPatterns, AccessRestriction furtherRestriction) {
+	private AccessRule accessRule;
+	private String messageTemplate;
+	public AccessRestriction(AccessRule accessRule, String messageTemplate) {
+		this.accessRule = accessRule;
 		this.messageTemplate = messageTemplate;
-		this.inclusionPatterns = inclusionPatterns;
-		this.exclusionPatterns = exclusionPatterns;
-		this.furtherRestriction = furtherRestriction;
 	}
-	/**
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	public boolean equals(Object object) {
-		if (this == object) 
-			return true;
-		if (!(object instanceof AccessRestriction))
-			return false;
-		AccessRestriction otherRestriction = (AccessRestriction) object;
-		if (!this.messageTemplate.equals(otherRestriction.messageTemplate)) 
-			return false;
-		if (this.inclusionPatterns != otherRestriction.inclusionPatterns) {
-			int length = this.inclusionPatterns == null ? 0 : this.inclusionPatterns.length;
-			int otherLength = otherRestriction.inclusionPatterns == null ? 0 : otherRestriction.inclusionPatterns.length;
-			if (length != otherLength)
-				return false;
-			for (int i = 0; i < length; i++) {
-				if (!CharOperation.equals(this.inclusionPatterns[i], otherRestriction.inclusionPatterns[i]))
-						return false;
-			}
-		}
-		if (this.exclusionPatterns != otherRestriction.exclusionPatterns) {
-			int length = this.exclusionPatterns == null ? 0 : this.exclusionPatterns.length;
-			int otherLength = otherRestriction.exclusionPatterns == null ? 0 : otherRestriction.exclusionPatterns.length;
-			if (length != otherLength)
-				return false;
-			for (int i = 0; i < length; i++) {
-				if (!CharOperation.equals(this.exclusionPatterns[i], otherRestriction.exclusionPatterns[i]))
-						return false;
-			}
-		}
-		if (this.furtherRestriction != otherRestriction.furtherRestriction) {
-			if (this.furtherRestriction == null || otherRestriction.furtherRestriction == null) 
-				return false;
-			if (!this.furtherRestriction.equals(otherRestriction.furtherRestriction))
-				return false;
-		}
-		return true;
-	}
-	/**
-	 * Select the first restriction which is violated when accessing a given type, or null if no restriction applies.
-	 * Type name is formed as: "java/lang/Object".
-	 */
-	public AccessRestriction getViolatedRestriction(char[] targetTypeName, char[] referringTypeName) {
-		
-		// check local inclusion/exclusion rules
-		if (this.inclusionPatterns != null || this.exclusionPatterns != null) {
-			if (Util.isExcluded(targetTypeName, this.inclusionPatterns, this.exclusionPatterns, false)) {
-				return this;
-			}
-		}		
-	// then check further restrictions
-		return this.furtherRestriction != null 
-						? this.furtherRestriction.getViolatedRestriction(targetTypeName, referringTypeName)
-						: null;
-	}
-	public char[][] getExclusionPatterns() {
-			return this.exclusionPatterns;
-	}
-	public char[][] getInclusionPatterns() {
-			return this.inclusionPatterns;
-	}
+	
 	/**
 	 * Returns readable description for problem reporting, 
 	 * message is expected to contain room for restricted type name
 	 * e.g. "{0} has restricted access"
 	 */
 	public String getMessageTemplate() {
-			return this.messageTemplate;
+		return this.messageTemplate;
 	}
 	
-	public String toString() {
-		StringBuffer buffer = new StringBuffer(20);
-		buffer
-			.append("AccessRestriction [includes:\"") //$NON-NLS-1$
-			.append(CharOperation.concatWith(this.inclusionPatterns,'/'))
-			.append("\"][excludes:\"") //$NON-NLS-1$
-			.append(CharOperation.concatWith(this.exclusionPatterns,'/'))
-			.append("\"][template:\"") //$NON-NLS-1$
-			.append(this.messageTemplate)
-			.append("\"]"); //$NON-NLS-1$
-		if (this.furtherRestriction != null) {
-			buffer.append('\n').append(this.furtherRestriction);
-		}
-		return buffer.toString();
+	public int getProblemId() {
+		return this.accessRule.problemId;
 	}
+
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.java
new file mode 100644
index 0000000..6c02c66
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+public class AccessRule {
+	
+	public char[] pattern;
+	public int problemId;
+	
+	public AccessRule(char[] pattern, int problemId) {
+		this.pattern = pattern;
+		this.problemId = problemId;
+	}
+	
+	public int hashCode() {
+		return this.problemId * 17 + CharOperation.hashCode(this.pattern);
+	}
+	
+	public boolean equals(Object obj) {
+		if (!(obj instanceof AccessRule)) return false;
+		AccessRule other = (AccessRule) obj;
+		if (this.problemId != other.problemId) return false;
+		return CharOperation.equals(this.pattern, other.pattern);
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("pattern="); //$NON-NLS-1$
+		buffer.append(this.pattern);
+		switch (this.problemId) {
+			case IProblem.ForbiddenReference:
+				buffer.append(" (NON ACCESSIBLE)"); //$NON-NLS-1$
+				break;
+			case IProblem.DiscouragedReference:
+				buffer.append(" (DISCOURAGED)"); //$NON-NLS-1$
+				break;
+			default:
+				buffer.append(" (ACCESSIBLE)"); //$NON-NLS-1$
+				break;
+		}
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
new file mode 100644
index 0000000..4a51ece
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.env;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
+
+/**
+ * Definition of a set of access rules used to flag forbidden references to non API code.
+ */
+public class AccessRuleSet {
+
+	private AccessRule[] accessRules;
+	public String messageTemplate;
+	
+	
+	public AccessRuleSet(AccessRule[] accessRules) {
+		this.accessRules = accessRules;
+	}
+	/**
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object object) {
+		if (this == object) 
+			return true;
+		if (!(object instanceof AccessRuleSet))
+			return false;
+		AccessRuleSet otherRuleSet = (AccessRuleSet) object;
+		if (!this.messageTemplate.equals(otherRuleSet.messageTemplate)) 
+			return false;
+		int rulesLength = this.accessRules.length;
+		if (rulesLength != otherRuleSet.accessRules.length) return false;
+		for (int i = 0; i < rulesLength; i++)
+			if (!this.accessRules[i].equals(otherRuleSet.accessRules[i]))
+				return false;
+		return true;
+	}
+	
+	public AccessRule[] getAccessRules() {
+		return this.accessRules;
+	}
+	
+	/**
+	 * Select the first access rule which is violated when accessing a given type, or null if no 'non accessible' access rule applies.
+	 * Target type file path is formed as: "org/eclipse/jdt/core/JavaCore.java".
+	 */
+	public AccessRestriction getViolatedRestriction(char[] targetTypeFilePath) {
+		
+		for (int i = 0, length = this.accessRules.length; i < length; i++) {
+			AccessRule accessRule = this.accessRules[i];
+			if (CharOperation.pathMatch(accessRule.pattern, targetTypeFilePath, true/*case sensitive*/, '/')) {
+				switch (accessRule.problemId) {
+					case IProblem.ForbiddenReference:
+					case IProblem.DiscouragedReference:
+						return new AccessRestriction(accessRule, this.messageTemplate);
+					default:
+						return null;
+				}
+			}
+		}
+		return null;
+	}
+	
+	public String toString() {
+		return toString(true/*wrap lines*/);
+	}
+	
+	public String toString(boolean wrap) {
+		StringBuffer buffer = new StringBuffer(200);
+		buffer.append("AccessRuleSet {"); //$NON-NLS-1$
+		if (wrap)
+			buffer.append('\n');
+		for (int i = 0, length = this.accessRules.length; i < length; i++) {
+			if (wrap)
+				buffer.append('\t');
+			AccessRule accessRule = this.accessRules[i];
+			buffer.append(accessRule);
+			if (wrap)
+				buffer.append('\n');
+			else if (i < length-1)
+				buffer.append(", "); //$NON-NLS-1$
+		}
+		buffer
+			.append("} [template:\"") //$NON-NLS-1$
+			.append(this.messageTemplate)
+			.append("\"]"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java
index 28211a1..e75609f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,6 +19,10 @@
  */
 Constant getConstant();
 /**
+ * Answer the name of the field.
+ */
+char[] getName();
+/**
  * Answer the resolved name of the receiver's type in the
  * class file format as specified in section 4.3.2 of the Java 2 VM spec.
  *
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
index 9f2ecd0..dcf83da 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -44,6 +44,13 @@
 char[] getGenericSignature();
 
 /**
+ * Answer the name of the method.
+ *
+ * For a constructor, answer <init> & <clinit> for a clinit method.
+ */
+char[] getSelector();
+
+/**
  * Answer the tagbits set according to the bits for annotations.
  */
 long getTagBits();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
index 8a781dc..4a996d0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
index f693287..ded9a1e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
index bbcef08..e7605bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java
index c6cb0ac..e84c249 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
index 91b5b4a..1ad7626 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
index 35684a0..c4eca9a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,9 +19,5 @@
 // We have added AccDeprecated & AccSynthetic.
 
 int getModifiers();
-/**
- * Answer the name of the field.
- */
 
-char[] getName();
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
index c742d2d..6ed1bad 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,13 +18,6 @@
 // We have added AccDeprecated
 int getModifiers();
 
-/**
- * Answer the name of the method.
- *
- * For a constructor, answer <init> & <clinit> for a clinit method.
- */
-char[] getSelector();
-
 boolean isConstructor();
 
 /**
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
index 414d190..37d2775 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
index 0005601..3d6be2d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
index a344384..0f9c9cf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java
index 5bbd9bc..93a6bba 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -29,17 +29,4 @@
  * Since Java 1.5, static imports can be defined.
  */ 
 int getModifiers();
-
-/**
- * Answer the name of the import.
- * A name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-char[] getName();	
-
-/**
- * Answer whether the import is on demand or not
- * On demand import names have no trailing star
- */
-boolean onDemand();
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
index 8eba3ab..56d2ed1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,15 +13,6 @@
 public interface ISourceMethod extends IGenericMethod {
 
 /**
- * Answer the unresolved names of the argument types
- * or null if the array is empty.
- *
- * A name is a simple name or a qualified, dot separated name.
- * For example, Hashtable or java.util.Hashtable.
- */
-
-char[][] getArgumentTypeNames();
-/**
  * Answer the source end position of the method's declaration.
  */
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
index 3464fe8..1e78554 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -36,16 +36,6 @@
 ISourceField[] getFields();
 
 /**
- * Answer the receiver's imports.
- *
- * An import is a qualified, dot separated name.
- * For example, java.util.Hashtable or java.lang.*.
- * A static import used 'static.' as its first fragment, for
- * example: static.java.util.Hashtable.*
- */
-ISourceImport[] getImports();
-
-/**
  * Answer the unresolved names of the receiver's interfaces
  * or null if the array is empty.
  *
@@ -82,14 +72,6 @@
 int getNameSourceStart();
 
 /**
- * Answer the qualified name of the receiver's package separated by periods
- * or null if its the default package.
- *
- * For example, {java.util.Hashtable}.
- */
-char[] getPackageName();
-
-/**
  * Answer the unresolved name of the receiver's superclass
  * or null if it does not have one.
  *
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
index 1f015d5..103d05a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
index d7dc642..0801089 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
index 4862742..ae7ba28 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
index 0069d50..f3b4a67 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
index 46b46a5..ce08eae 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 3219a62..21d5f14 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
index e609ae1..9bbcb22 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
index 221666b..3524665 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java
index 0d83e74..d07caeb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
index 9f1ed05..cb72533 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
index 5cd28eb..1ac9f9a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
index 88cd296..52e7f2a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -73,6 +73,8 @@
 					// current storage is shorter -> grow current (could maybe reuse otherInits extra storage?)
 					System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length);
 					System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length);
+					System.arraycopy(extraDefiniteNulls, 0, (extraDefiniteNulls = new long[otherLength]), 0, length);
+					System.arraycopy(extraDefiniteNonNulls, 0, (extraDefiniteNonNulls = new long[otherLength]), 0, length);					
 					for (; i < length; i++) {
 						extraDefiniteInits[i] |= otherInits.extraDefiniteInits[i];
 						extraPotentialInits[i] |= otherInits.extraPotentialInits[i];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java
index e85214f..4eb624b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java
index 9a5e56a..d73ea9a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java
index d70f8a3..ddf344a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index f7f22e3..703c0f0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -49,6 +49,7 @@
 	public static final String OPTION_ReportLocalVariableHiding = "org.eclipse.jdt.core.compiler.problem.localVariableHiding"; //$NON-NLS-1$
 	public static final String OPTION_ReportSpecialParameterHidingField = "org.eclipse.jdt.core.compiler.problem.specialParameterHidingField"; //$NON-NLS-1$
 	public static final String OPTION_ReportFieldHiding = "org.eclipse.jdt.core.compiler.problem.fieldHiding"; //$NON-NLS-1$
+	public static final String OPTION_ReportTypeParameterHiding = "org.eclipse.jdt.core.compiler.problem.typeParameterHiding"; //$NON-NLS-1$
 	public static final String OPTION_ReportPossibleAccidentalBooleanAssignment = "org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment"; //$NON-NLS-1$
 	public static final String OPTION_ReportNonExternalizedStringLiteral = "org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral"; //$NON-NLS-1$
 	public static final String OPTION_ReportIncompatibleNonInheritedInterfaceMethod = "org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod"; //$NON-NLS-1$
@@ -92,11 +93,12 @@
 	public static final String OPTION_InlineJsr = "org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode"; //$NON-NLS-1$
 	public static final String OPTION_ReportNullReference = "org.eclipse.jdt.core.compiler.problem.nullReference"; //$NON-NLS-1$
 	public static final String OPTION_ReportAutoboxing = "org.eclipse.jdt.core.compiler.problem.autoboxing"; //$NON-NLS-1$
+	public static final String OPTION_ReportAnnotationSuperInterface = "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingOverrideAnnotation = "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"; //$NON-NLS-1$
+	public static final String OPTION_ReportMissingDeprecatedAnnotation = "org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation"; //$NON-NLS-1$
+	public static final String OPTION_ReportIncompleteEnumSwitch = "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
 	public static final String OPTION_ReportForbiddenReference =  "org.eclipse.jdt.core.compiler.problem.forbiddenReference"; //$NON-NLS-1$
-	public static final String OPTION_ImportRestrictionInclude = "org.eclipse.jdt.core.compiler.accessRestriction.import.include"; //$NON-NLS-1$
-	public static final String OPTION_ImportRestrictionExclude = "org.eclipse.jdt.core.compiler.accessRestriction.import.exclude"; //$NON-NLS-1$
-	public static final String OPTION_ExportRestrictionInclude = "org.eclipse.jdt.core.compiler.accessRestriction.export.include"; //$NON-NLS-1$
-	public static final String OPTION_ExportRestrictionExclude = "org.eclipse.jdt.core.compiler.accessRestriction.export.exclude"; //$NON-NLS-1$
+	public static final String OPTION_ReportDiscouragedReference =  "org.eclipse.jdt.core.compiler.problem.discouragedReference"; //$NON-NLS-1$
 	
 	// Backward compatibility
 	public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$
@@ -169,7 +171,13 @@
 	public static final long VarargsArgumentNeedCast = ASTNode.Bit36L;
 	public static final long NullReference = ASTNode.Bit37L;
 	public static final long Autoboxing = ASTNode.Bit38L;
-
+	public static final long AnnotationSuperInterface = ASTNode.Bit39L;
+	public static final long TypeParameterHiding = ASTNode.Bit40L;
+	public static final long MissingOverrideAnnotation = ASTNode.Bit41L;
+	public static final long IncompleteEnumSwitch = ASTNode.Bit42L;
+	public static final long MissingDeprecatedAnnotation = ASTNode.Bit43L;
+	public static final long DiscouragedReference = ASTNode.Bit44L;
+	
 	// Default severity level for handlers
 	public long errorThreshold = 0;
 		
@@ -190,6 +198,10 @@
 		| MissingSerialVersion
 		| VarargsArgumentNeedCast
 		| ForbiddenReference
+		| DiscouragedReference
+		| AnnotationSuperInterface
+		| TypeParameterHiding
+		| FinalParameterBound
 		/*| NullReference*/;
 
 	// Debug attributes
@@ -225,12 +237,6 @@
 	// max problems per compilation unit
 	public int maxProblemsPerUnit = 100; // no more than 100 problems per default
 	
-	// access restrictions
-	public char[][] importRestrictionInclude;
-	public char[][] importRestrictionExclude;
-	public char[][] exportRestrictionInclude;
-	public char[][] exportRestrictionExclude;
-	
 	// tags used to recognize tasks in comments
 	public char[][] taskTags = null;
 	public char[][] taskPriorites = null;
@@ -314,6 +320,7 @@
 		optionsMap.put(OPTION_ReportUnusedPrivateMember, getSeverityString(UnusedPrivateMember)); 
 		optionsMap.put(OPTION_ReportLocalVariableHiding, getSeverityString(LocalVariableHiding)); 
 		optionsMap.put(OPTION_ReportFieldHiding, getSeverityString(FieldHiding)); 
+		optionsMap.put(OPTION_ReportTypeParameterHiding, getSeverityString(TypeParameterHiding)); 
 		optionsMap.put(OPTION_ReportPossibleAccidentalBooleanAssignment, getSeverityString(AccidentalBooleanAssign)); 
 		optionsMap.put(OPTION_ReportEmptyStatement, getSeverityString(EmptyStatement)); 
 		optionsMap.put(OPTION_ReportAssertIdentifier, getSeverityString(AssertUsedAsAnIdentifier)); 
@@ -321,6 +328,9 @@
 		optionsMap.put(OPTION_ReportUndocumentedEmptyBlock, getSeverityString(UndocumentedEmptyBlock)); 
 		optionsMap.put(OPTION_ReportUnnecessaryTypeCheck, getSeverityString(UnnecessaryTypeCheck)); 
 		optionsMap.put(OPTION_ReportUnnecessaryElse, getSeverityString(UnnecessaryElse)); 
+		optionsMap.put(OPTION_ReportAutoboxing, getSeverityString(Autoboxing)); 
+		optionsMap.put(OPTION_ReportAnnotationSuperInterface, getSeverityString(AnnotationSuperInterface)); 
+		optionsMap.put(OPTION_ReportIncompleteEnumSwitch, getSeverityString(IncompleteEnumSwitch)); 
 		optionsMap.put(OPTION_ReportInvalidJavadoc, getSeverityString(InvalidJavadoc));
 		optionsMap.put(OPTION_ReportInvalidJavadocTagsVisibility, getVisibilityString(this.reportInvalidJavadocTagsVisibility));
 		optionsMap.put(OPTION_ReportInvalidJavadocTags, this.reportInvalidJavadocTags ? ENABLED : DISABLED);
@@ -340,7 +350,11 @@
 		optionsMap.put(OPTION_ReportFinalParameterBound, getSeverityString(FinalParameterBound));
 		optionsMap.put(OPTION_ReportMissingSerialVersion, getSeverityString(MissingSerialVersion));
 		optionsMap.put(OPTION_ReportForbiddenReference, getSeverityString(ForbiddenReference));
+		optionsMap.put(OPTION_ReportDiscouragedReference, getSeverityString(DiscouragedReference));
 		optionsMap.put(OPTION_ReportVarargsArgumentNeedCast, getSeverityString(VarargsArgumentNeedCast)); 
+		optionsMap.put(OPTION_ReportMissingOverrideAnnotation, getSeverityString(MissingOverrideAnnotation));
+		optionsMap.put(OPTION_ReportMissingDeprecatedAnnotation, getSeverityString(MissingDeprecatedAnnotation));
+		optionsMap.put(OPTION_ReportIncompleteEnumSwitch, getSeverityString(IncompleteEnumSwitch));
 		optionsMap.put(OPTION_Compliance, versionFromJdkLevel(this.complianceLevel)); 
 		optionsMap.put(OPTION_Source, versionFromJdkLevel(this.sourceLevel)); 
 		optionsMap.put(OPTION_TargetPlatform, versionFromJdkLevel(this.targetJDK)); 
@@ -355,10 +369,6 @@
 		optionsMap.put(OPTION_ReportSpecialParameterHidingField, this.reportSpecialParameterHidingField ? ENABLED : DISABLED); 
 		optionsMap.put(OPTION_MaxProblemPerUnit, String.valueOf(this.maxProblemsPerUnit));
 		optionsMap.put(OPTION_InlineJsr, this.inlineJsrBytecode ? ENABLED : DISABLED); 
-		optionsMap.put(OPTION_ImportRestrictionInclude, this.importRestrictionInclude == null ? "" : new String(CharOperation.concatWith(this.importRestrictionInclude,','))); //$NON-NLS-1$
-		optionsMap.put(OPTION_ImportRestrictionExclude, this.importRestrictionExclude == null ? "" : new String(CharOperation.concatWith(this.importRestrictionExclude,','))); //$NON-NLS-1$
-		optionsMap.put(OPTION_ImportRestrictionInclude, this.exportRestrictionInclude == null ? "" : new String(CharOperation.concatWith(this.exportRestrictionInclude,','))); //$NON-NLS-1$
-		optionsMap.put(OPTION_ExportRestrictionExclude, this.exportRestrictionExclude == null ? "" : new String(CharOperation.concatWith(this.exportRestrictionExclude,','))); //$NON-NLS-1$
 		optionsMap.put(OPTION_ReportNullReference, getSeverityString(NullReference)); 
 		return optionsMap;		
 	}
@@ -534,46 +544,6 @@
 				this.isTaskCaseSensitive = false;
 			}
 		}
-		if ((optionValue = optionsMap.get(OPTION_ImportRestrictionInclude)) != null) {
-			if (optionValue instanceof String) {
-				String stringValue = (String) optionValue;
-				if (stringValue.length() == 0) {
-					this.importRestrictionInclude = null;
-				} else {
-					this.importRestrictionInclude = CharOperation.splitAndTrimOn(',', stringValue.toCharArray());
-				}
-			}
-		}	
-		if ((optionValue = optionsMap.get(OPTION_ImportRestrictionExclude)) != null) {
-			if (optionValue instanceof String) {
-				String stringValue = (String) optionValue;
-				if (stringValue.length() == 0) {
-					this.importRestrictionExclude = null;
-				} else {
-					this.importRestrictionExclude = CharOperation.splitAndTrimOn(',', stringValue.toCharArray());
-				}
-			}
-		}			
-		if ((optionValue = optionsMap.get(OPTION_ExportRestrictionInclude)) != null) {
-			if (optionValue instanceof String) {
-				String stringValue = (String) optionValue;
-				if (stringValue.length() == 0) {
-					this.exportRestrictionInclude = null;
-				} else {
-					this.exportRestrictionInclude = CharOperation.splitAndTrimOn(',', stringValue.toCharArray());
-				}
-			}
-		}			
-		if ((optionValue = optionsMap.get(OPTION_ExportRestrictionExclude)) != null) {
-			if (optionValue instanceof String) {
-				String stringValue = (String) optionValue;
-				if (stringValue.length() == 0) {
-					this.exportRestrictionExclude = null;
-				} else {
-					this.exportRestrictionExclude = CharOperation.splitAndTrimOn(',', stringValue.toCharArray());
-				}
-			}
-		}			
 		if ((optionValue = optionsMap.get(OPTION_InlineJsr)) != null) {
 			if (this.targetJDK < JDK1_5) { // only optional if target < 1.5 (inlining on from 1.5 on)
 				if (ENABLED.equals(optionValue)) {
@@ -596,6 +566,7 @@
 		if ((optionValue = optionsMap.get(OPTION_ReportSyntheticAccessEmulation)) != null) updateSeverity(AccessEmulation, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportLocalVariableHiding)) != null) updateSeverity(LocalVariableHiding, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportFieldHiding)) != null) updateSeverity(FieldHiding, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportTypeParameterHiding)) != null) updateSeverity(TypeParameterHiding, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportPossibleAccidentalBooleanAssignment)) != null) updateSeverity(AccidentalBooleanAssign, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportEmptyStatement)) != null) updateSeverity(EmptyStatement, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportNonExternalizedStringLiteral)) != null) updateSeverity(NonExternalizedString, optionValue);
@@ -614,9 +585,14 @@
 		if ((optionValue = optionsMap.get(OPTION_ReportFinalParameterBound)) != null) updateSeverity(FinalParameterBound, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportMissingSerialVersion)) != null) updateSeverity(MissingSerialVersion, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportForbiddenReference)) != null) updateSeverity(ForbiddenReference, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportDiscouragedReference)) != null) updateSeverity(DiscouragedReference, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportVarargsArgumentNeedCast)) != null) updateSeverity(VarargsArgumentNeedCast, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportNullReference)) != null) updateSeverity(NullReference, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportAutoboxing)) != null) updateSeverity(Autoboxing, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportAnnotationSuperInterface)) != null) updateSeverity(AnnotationSuperInterface, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingOverrideAnnotation)) != null) updateSeverity(MissingOverrideAnnotation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportMissingDeprecatedAnnotation)) != null) updateSeverity(MissingDeprecatedAnnotation, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportIncompleteEnumSwitch)) != null) updateSeverity(IncompleteEnumSwitch, optionValue);
 		
 		// Javadoc options
 		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
@@ -728,6 +704,7 @@
 		buf.append("\n\t- unused private member: ").append(getSeverityString(UnusedPrivateMember)); //$NON-NLS-1$
 		buf.append("\n\t- local variable hiding another variable: ").append(getSeverityString(LocalVariableHiding)); //$NON-NLS-1$
 		buf.append("\n\t- field hiding another variable: ").append(getSeverityString(FieldHiding)); //$NON-NLS-1$
+		buf.append("\n\t- type parameter hiding another type: ").append(getSeverityString(TypeParameterHiding)); //$NON-NLS-1$
 		buf.append("\n\t- possible accidental boolean assignment: ").append(getSeverityString(AccidentalBooleanAssign)); //$NON-NLS-1$
 		buf.append("\n\t- superfluous semicolon: ").append(getSeverityString(EmptyStatement)); //$NON-NLS-1$
 		buf.append("\n\t- uncommented empty block: ").append(getSeverityString(UndocumentedEmptyBlock)); //$NON-NLS-1$
@@ -736,7 +713,7 @@
 		buf.append("\n\t\t+ invalid javadoc: ").append(getSeverityString(InvalidJavadoc)); //$NON-NLS-1$
 		buf.append("\n\t\t+ report invalid javadoc tags: ").append(this.reportInvalidJavadocTags ? ENABLED : DISABLED); //$NON-NLS-1$
 		buf.append("\n\t\t\t* deprecated references: ").append(this.reportInvalidJavadocTagsDeprecatedRef ? ENABLED : DISABLED); //$NON-NLS-1$
-		buf.append("\n\t\t\t* not visble references: ").append(this.reportInvalidJavadocTagsNotVisibleRef ? ENABLED : DISABLED); //$NON-NLS-1$
+		buf.append("\n\t\t\t* not visible references: ").append(this.reportInvalidJavadocTagsNotVisibleRef ? ENABLED : DISABLED); //$NON-NLS-1$
 		buf.append("\n\t\t+ visibility level to report invalid javadoc tags: ").append(getVisibilityString(this.reportInvalidJavadocTagsVisibility)); //$NON-NLS-1$
 		buf.append("\n\t\t+ missing javadoc tags: ").append(getSeverityString(MissingJavadocTags)); //$NON-NLS-1$
 		buf.append("\n\t\t+ visibility level to report missing javadoc tags: ").append(getVisibilityString(this.reportMissingJavadocTagsVisibility)); //$NON-NLS-1$
@@ -769,12 +746,13 @@
 		buf.append("\n\t- missing serialVersionUID: ").append(getSeverityString(MissingSerialVersion)); //$NON-NLS-1$
 		buf.append("\n\t- varargs argument need cast: ").append(getSeverityString(VarargsArgumentNeedCast)); //$NON-NLS-1$
 		buf.append("\n\t- forbidden reference to type with access restriction: ").append(getSeverityString(ForbiddenReference)); //$NON-NLS-1$
-		buf.append("\n\t- import access restriction includes: ").append(this.importRestrictionInclude == null ? "" : new String(CharOperation.concatWith(this.importRestrictionInclude,',')));  //$NON-NLS-1$ //$NON-NLS-2$
-		buf.append("\n\t- import access restriction excludes: ").append(this.importRestrictionExclude == null ? "" : new String(CharOperation.concatWith(this.importRestrictionExclude,',')));  //$NON-NLS-1$ //$NON-NLS-2$
-		buf.append("\n\t- export access restriction includes: ").append(this.exportRestrictionInclude == null ? "" : new String(CharOperation.concatWith(this.exportRestrictionInclude,',')));  //$NON-NLS-1$ //$NON-NLS-2$
-		buf.append("\n\t- export access restriction excludes: ").append(this.exportRestrictionExclude == null ? "" : new String(CharOperation.concatWith(this.exportRestrictionExclude,',')));  //$NON-NLS-1$ //$NON-NLS-2$
+		buf.append("\n\t- discouraged reference to type with access restriction: ").append(getSeverityString(DiscouragedReference)); //$NON-NLS-1$
 		buf.append("\n\t- null reference: ").append(getSeverityString(NullReference)); //$NON-NLS-1$
 		buf.append("\n\t- autoboxing: ").append(getSeverityString(Autoboxing)); //$NON-NLS-1$
+		buf.append("\n\t- annotation super interface: ").append(getSeverityString(AnnotationSuperInterface)); //$NON-NLS-1$
+		buf.append("\n\t- missing @Override annotation: ").append(getSeverityString(MissingOverrideAnnotation)); //$NON-NLS-1$		
+		buf.append("\n\t- missing @Deprecated annotation: ").append(getSeverityString(MissingDeprecatedAnnotation)); //$NON-NLS-1$		
+		buf.append("\n\t- incomplete enum switch: ").append(getSeverityString(IncompleteEnumSwitch)); //$NON-NLS-1$		
 		return buf.toString();
 	}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
index 3130eed..fe5bb5a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,7 +13,7 @@
 import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 
 public abstract class Constant implements TypeIds, OperatorIds {
 	
@@ -25,12 +25,12 @@
 	
 	public boolean booleanValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"boolean")); //$NON-NLS-1$ //$NON-NLS-2$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "boolean" })); //$NON-NLS-1$
 	}
 
 	public byte byteValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"byte")); //$NON-NLS-1$ //$NON-NLS-2$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "byte" })); //$NON-NLS-1$
 	}
 
 	public final Constant castTo(int conversionToTargetType){
@@ -205,7 +205,7 @@
 	
 	public char charValue() {
 		
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"char")); //$NON-NLS-1$ //$NON-NLS-2$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "char" })); //$NON-NLS-1$
 	}
 	
 	public static final Constant computeConstantOperation(Constant cst, int id, int operator) {
@@ -1514,12 +1514,12 @@
 
 	public double doubleValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"double")); //$NON-NLS-2$ //$NON-NLS-1$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "double" })); //$NON-NLS-1$
 	}
 
 	public float floatValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"float")); //$NON-NLS-2$ //$NON-NLS-1$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "float" })); //$NON-NLS-1$
 	}
 
 	public static Constant fromValue(byte value) {
@@ -1569,22 +1569,22 @@
 
 	public int intValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"int")); //$NON-NLS-2$ //$NON-NLS-1$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "int" })); //$NON-NLS-1$
 	}
 
 	public long longValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotCastedInto",typeName(),"long")); //$NON-NLS-2$ //$NON-NLS-1$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "long" })); //$NON-NLS-1$
 	}
 
 	public short shortValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotConvertedTo",typeName(),"short")); //$NON-NLS-2$ //$NON-NLS-1$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotConvertedTo, new String[] { typeName(), "short" })); //$NON-NLS-1$
 	}
 
 	public String stringValue() {
 
-		throw new ShouldNotImplement(Util.bind("constant.cannotConvertedTo",typeName(),"String")); //$NON-NLS-1$ //$NON-NLS-2$
+		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotConvertedTo, new String[] { typeName(), "String" })); //$NON-NLS-1$
 	}
 
 	public String toString(){
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java
index ca72801..d6ff773 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java
index 6caec4d..53a0c51 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java
index 9ae827d..7c2d2ed 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java
index 8d54e90..149ea6d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java
index c730665..20f22c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
index f645b0a..43baa94 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java
index 0bad92d..df8eb6e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java
index 51ab819..99b8d74 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
index 541002b..faccf47 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -42,28 +42,38 @@
 
 /**
  * Collect the substitutes into a map for certain type variables inside the receiver type
- * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
+ * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
  */
-public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
-    if (otherType.isArrayType()) {
-        int otherDim = otherType.dimensions();
-        if (otherDim == this.dimensions) {
-		    this.leafComponentType.collectSubstitutes(otherType.leafComponentType(), substitutes);
-        } else if (otherDim > this.dimensions) {
-            ArrayBinding otherReducedType = this.environment.createArrayType(otherType.leafComponentType(), otherDim - this.dimensions);
-            this.leafComponentType.collectSubstitutes(otherReducedType, substitutes);
-        }
-    } 
+public void collectSubstitutes(Scope scope, TypeBinding otherType, Map substitutes, int constraint) {
+	
+	if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
+	if (otherType == NullBinding) return;
+	
+	switch(otherType.kind()) {
+		case Binding.ARRAY_TYPE :
+	        int otherDim = otherType.dimensions();
+	        if (otherDim == this.dimensions) {
+			    this.leafComponentType.collectSubstitutes(scope, otherType.leafComponentType(), substitutes, constraint);
+	        } else if (otherDim > this.dimensions) {
+	            ArrayBinding otherReducedType = this.environment.createArrayType(otherType.leafComponentType(), otherDim - this.dimensions);
+	            this.leafComponentType.collectSubstitutes(scope, otherReducedType, substitutes, constraint);
+	        }
+			break;
+		case Binding.TYPE_PARAMETER :
+			//TypeVariableBinding variable = (TypeVariableBinding) otherType;
+			// TODO (philippe) should consider array bounds, and recurse
+			break;
+	}
 }
 
 /*
  * brakets leafUniqueKey
  * p.X[][] --> [[Lp/X;
  */
-public char[] computeUniqueKey() {
+public char[] computeUniqueKey(boolean withAccessFlags) {
 	char[] brackets = new char[dimensions];
 	for (int i = dimensions - 1; i >= 0; i--) brackets[i] = '[';
-	return CharOperation.concat(brackets, this.leafComponentType.computeUniqueKey());
+	return CharOperation.concat(brackets, this.leafComponentType.computeUniqueKey(false/*without access flags*/));
  }
 	
 /**
@@ -133,20 +143,20 @@
 	if (this == right)
 		return true;
 
-	if (right.isArrayType()) {
-		ArrayBinding rightArray = (ArrayBinding) right;
-		if (rightArray.leafComponentType.isBaseType())
-			return false; // relying on the fact that all equal arrays are identical
-		if (dimensions == rightArray.dimensions)
-			return leafComponentType.isCompatibleWith(rightArray.leafComponentType);
-		if (dimensions < rightArray.dimensions)
-			return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]'
-	} else {
-		if (right.isBaseType())
+	switch (right.kind()) {
+		case Binding.ARRAY_TYPE :
+			ArrayBinding rightArray = (ArrayBinding) right;
+			if (rightArray.leafComponentType.isBaseType())
+				return false; // relying on the fact that all equal arrays are identical
+			if (dimensions == rightArray.dimensions)
+				return leafComponentType.isCompatibleWith(rightArray.leafComponentType);
+			if (dimensions < rightArray.dimensions)
+				return false; // cannot assign 'String[]' into 'Object[][]' but can assign 'byte[][]' into 'Object[]'
+			break;
+		case Binding.BASE_TYPE :
 			return false;
-		if (right.isWildcard()) {
+		case Binding.WILDCARD_TYPE :
 		    return ((WildcardBinding) right).boundCheck(this);
-		}
 	}
 	//Check dimensions - Java does not support explicitly sized dimensions for types.
 	//However, if it did, the type checking support would go here.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
index 501e237..96f3d51 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,6 +23,13 @@
 		this.constantPoolName = constantPoolName;
 	}
 
+	/**
+	 * int -> I
+	 */
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+		return constantPoolName();
+	}
+	
 	/* Answer the receiver's constant pool name.
 	*/
 	public char[] constantPoolName() {
@@ -163,7 +170,12 @@
 				return false;
 		}
 	}
-
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#kind()
+	 */
+	public int kind() {
+		return Binding.BASE_TYPE;
+	}
 	public char[] qualifiedSourceName() {
 		return simpleName;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypes.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypes.java
index a6e82bf..8c18693 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypes.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypes.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 1523121..9cbcb0d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -137,10 +137,12 @@
 }
 
 public FieldBinding[] availableFields() {
+	if ((tagBits & AreFieldsComplete) != 0)
+		return fields;
+
 	FieldBinding[] availableFields = new FieldBinding[fields.length];
 	int count = 0;
-	
-	for (int i = 0; i < fields.length;i++) {
+	for (int i = 0; i < fields.length; i++) {
 		try {
 			availableFields[count] = resolveTypeFor(fields[i]);
 			count++;
@@ -148,19 +150,17 @@
 			// silent abort
 		}
 	}
-	
-	System.arraycopy(availableFields, 0, availableFields = new FieldBinding[count], 0, count);
+	if (count < availableFields.length)
+		System.arraycopy(availableFields, 0, availableFields = new FieldBinding[count], 0, count);
 	return availableFields;
 }
-
 public MethodBinding[] availableMethods() {
-	if ((modifiers & AccUnresolved) == 0)
+	if ((tagBits & AreMethodsComplete) != 0)
 		return methods;
-		
+
 	MethodBinding[] availableMethods = new MethodBinding[methods.length];
 	int count = 0;
-	
-	for (int i = 0; i < methods.length;i++) {
+	for (int i = 0; i < methods.length; i++) {
 		try {
 			availableMethods[count] = resolveTypesFor(methods[i]);
 			count++;
@@ -168,15 +168,10 @@
 			// silent abort
 		}
 	}
-	System.arraycopy(availableMethods, 0, availableMethods = new MethodBinding[count], 0, count);
+	if (count < availableMethods.length)
+		System.arraycopy(availableMethods, 0, availableMethods = new MethodBinding[count], 0, count);
 	return availableMethods;
 }
-
-public int kind() {
-	if (this.typeVariables != NoTypeVariables) return Binding.GENERIC_TYPE;
-	return Binding.TYPE;
-}	
-
 void cachePartsFrom(IBinaryType binaryType, boolean needFieldsAndMethods) {
 	// default initialization for super-interfaces early, in case some aborting compilation error occurs,
 	// and still want to use binaries passed that point (e.g. type hierarchy resolver, see bug 63748).
@@ -279,25 +274,26 @@
 		if (size > 0) {
 			this.fields = new FieldBinding[size];
 			boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5;
+			boolean isViewedAsDeprecated = isViewedAsDeprecated();
 			for (int i = 0; i < size; i++) {
 				IBinaryField binaryField = iFields[i];
 				char[] fieldSignature = use15specifics ? binaryField.getGenericSignature() : null;
-				TypeBinding type = fieldSignature == null
-					? environment.getTypeFromSignature(binaryField.getTypeName(), 0, -1, false, this)
+				TypeBinding type = fieldSignature == null 
+					? environment.getTypeFromSignature(binaryField.getTypeName(), 0, -1, false, this) 
 					: environment.getTypeFromTypeSignature(new SignatureWrapper(fieldSignature), NoTypeVariables, this);
-				FieldBinding field =
+				FieldBinding field = 
 					new FieldBinding(
-						binaryField.getName(),
-						type,
-						binaryField.getModifiers() | AccUnresolved,
-						this,
+						binaryField.getName(), 
+						type, 
+						binaryField.getModifiers() | AccUnresolved, 
+						this, 
 						binaryField.getConstant());
 				field.id = i; // ordinal
-				if (use15specifics) {
+				if (use15specifics)
 					field.tagBits |= binaryField.getTagBits();
-				}
+				if (isViewedAsDeprecated && !field.isDeprecated())
+					field.modifiers |= AccDeprecatedImplicitly;
 				this.fields[i] = field;
-
 			}
 		}
 	}
@@ -337,7 +333,7 @@
 				while ((nextChar = methodDescriptor[++end]) == '['){/*empty*/}
 				if (nextChar == 'L')
 					while ((nextChar = methodDescriptor[++end]) != ';'){/*empty*/}
-	
+
 				if (i >= startIndex)   // skip the synthetic arg if necessary
 					parameters[i - startIndex] = environment.getTypeFromSignature(methodDescriptor, index, end, false, this);
 				index = end + 1;
@@ -373,12 +369,8 @@
 				wrapper.start++; // skip ')'
 			} else {
 				java.util.ArrayList types = new java.util.ArrayList(2);
-				int startIndex = (method.isConstructor() && isMemberType() && !isStatic()) ? 1 : 0;
-				if (startIndex == 1)
-					environment.getTypeFromTypeSignature(wrapper, typeVars, this); // skip synthetic argument
-				while (wrapper.signature[wrapper.start] != ')') {
+				while (wrapper.signature[wrapper.start] != ')')
 					types.add(environment.getTypeFromTypeSignature(wrapper, typeVars, this));
-				}
 				wrapper.start++; // skip ')'
 				parameters = new TypeBinding[types.size()];
 				types.toArray(parameters);
@@ -413,14 +405,12 @@
 	MethodBinding result = method.isConstructor()
 		? new MethodBinding(methodModifiers, parameters, exceptions, this)
 		: new MethodBinding(methodModifiers, method.getSelector(), returnType, parameters, exceptions, this);
-	if (use15specifics) {
+	if (use15specifics)
 		result.tagBits |= method.getTagBits();
-	}
 	result.typeVariables = typeVars;
 	// fixup the declaring element of the type variable
-	for (int i = 0, length = typeVars.length; i < length; i++) {
+	for (int i = 0, length = typeVars.length; i < length; i++)
 		typeVars[i].declaringElement = result;
-	}
 	return result;
 }
 /**
@@ -453,18 +443,26 @@
 		return;
 	}
 
+	boolean isViewedAsDeprecated = isViewedAsDeprecated();
 	this.methods = new MethodBinding[total];
 	if (total == initialTotal) {
-		for (int i = 0; i < initialTotal; i++)
-			this.methods[i] = createMethod(iMethods[i], sourceLevel);
+		for (int i = 0; i < initialTotal; i++) {
+			MethodBinding method = createMethod(iMethods[i], sourceLevel);
+			if (isViewedAsDeprecated && !method.isDeprecated())
+				method.modifiers |= AccDeprecatedImplicitly;
+			this.methods[i] = method;
+		}
 	} else {
-		for (int i = 0, index = 0; i < initialTotal; i++)
-			if (iClinit != i && (toSkip == null || toSkip[i] != -1))
-				this.methods[index++] = createMethod(iMethods[i], sourceLevel);
+		for (int i = 0, index = 0; i < initialTotal; i++) {
+			if (iClinit != i && (toSkip == null || toSkip[i] != -1)) {
+				MethodBinding method = createMethod(iMethods[i], sourceLevel);
+				if (isViewedAsDeprecated && !method.isDeprecated())
+					method.modifiers |= AccDeprecatedImplicitly;
+				this.methods[index++] = method;
+			}
+		}
 	}
-	modifiers |= AccUnresolved; // until methods() is sent
 }
-
 private TypeVariableBinding[] createTypeVariables(SignatureWrapper wrapper, Binding declaringElement) {
 	// detect all type variables first
 	char[] typeSignature = wrapper.signature;
@@ -505,12 +503,10 @@
 	}
 	return result;
 }
-
 /* Answer the receiver's enclosing type... null if the receiver is a top level type.
 *
 * NOTE: enclosingType of a binary type is resolved when needed
 */
-
 public ReferenceBinding enclosingType() {
 	if ((this.tagBits & HasUnresolvedEnclosingType) == 0)
 		return this.enclosingType;
@@ -523,13 +519,21 @@
 	return this.enclosingType;
 }
 // NOTE: the type of each field of a binary type is resolved when needed
-
 public FieldBinding[] fields() {
+	if ((tagBits & AreFieldsComplete) != 0)
+		return fields;
+
 	for (int i = fields.length; --i >= 0;)
 		resolveTypeFor(fields[i]);
+	tagBits |= AreFieldsComplete;
 	return fields;
 }
-
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
+ */
+public char[] genericTypeSignature() {
+	return computeGenericTypeSignature(this.typeVariables);
+}
 // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
 	int argCount = argumentTypes.length;
@@ -548,7 +552,6 @@
 }
 // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
 // searches up the hierarchy as long as no potential (but not exact) match was found.
-
 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
 	// sender from refScope calls recordTypeReference(this)
 	int argCount = argumentTypes.length;
@@ -571,12 +574,12 @@
 
 	if (foundNothing) {
 		if (isInterface()) {
-			 if (superInterfaces.length == 1) {
+			 if (superInterfaces().length == 1) { // ensure superinterfaces are resolved before checking
 				if (refScope != null)
 					refScope.recordTypeReference(superInterfaces[0]);
 				return superInterfaces[0].getExactMethod(selector, argumentTypes, refScope);
 			 }
-		} else if (superclass != null) {
+		} else if (superclass() != null) { // ensure superclass is resolved before checking
 			if (refScope != null)
 				refScope.recordTypeReference(superclass);
 			return superclass.getExactMethod(selector, argumentTypes, refScope);
@@ -585,7 +588,6 @@
 	return null;
 }
 // NOTE: the type of a field of a binary type is resolved when needed
-
 public FieldBinding getField(char[] fieldName, boolean needResolve) {
 	int fieldLength = fieldName.length;
 	for (int f = fields.length; --f >= 0;) {
@@ -614,7 +616,6 @@
 	return null;
 }
 // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
-
 public MethodBinding[] getMethods(char[] selector) {
 	int count = 0;
 	int lastIndex = -1;
@@ -645,7 +646,6 @@
     return this.memberTypes.length > 0;
 }
 // NOTE: member types of binary types are resolved when needed
-
 public TypeVariableBinding getTypeVariable(char[] variableName) {
 	TypeVariableBinding variable = super.getTypeVariable(variableName);
 	variable.resolve(this.environment);
@@ -692,24 +692,25 @@
  * or for generic types, true if compared to its raw type.
  */
 public boolean isEquivalentTo(TypeBinding otherType) {
-	
-    if (this == otherType) return true;
-    if (otherType == null) return false;
-    switch(otherType.kind()) {
-
-    	case Binding.WILDCARD_TYPE :
+	if (this == otherType) return true;
+	if (otherType == null) return false;
+	switch(otherType.kind()) {
+		case Binding.WILDCARD_TYPE :
 			return ((WildcardBinding) otherType).boundCheck(this);
-
 		case Binding.RAW_TYPE :
 			return otherType.erasure() == this;
-    }
+	}
 	return false;
 }
 public boolean isGenericType() {
     return this.typeVariables != NoTypeVariables;
 }
+public int kind() {
+	if (this.typeVariables != NoTypeVariables)
+		return Binding.GENERIC_TYPE;
+	return Binding.TYPE;
+}	
 // NOTE: member types of binary types are resolved when needed
-
 public ReferenceBinding[] memberTypes() {
  	if ((this.tagBits & HasUnresolvedMemberTypes) == 0)
 		return this.memberTypes;
@@ -723,14 +724,13 @@
 	return this.memberTypes;
 }
 // NOTE: the return type, arg & exception types of each method of a binary type are resolved when needed
-
 public MethodBinding[] methods() {
-	if ((modifiers & AccUnresolved) == 0)
+	if ((tagBits & AreMethodsComplete) != 0)
 		return methods;
 
 	for (int i = methods.length; --i >= 0;)
 		resolveTypesFor(methods[i]);
-	modifiers &= ~AccUnresolved;
+	tagBits |= AreMethodsComplete;
 	return methods;
 }
 private FieldBinding resolveTypeFor(FieldBinding field) {
@@ -756,12 +756,10 @@
 	method.modifiers &= ~AccUnresolved;
 	return method;
 }
-
 /* Answer the receiver's superclass... null if the receiver is Object or an interface.
 *
 * NOTE: superclass of a binary type is resolved when needed
 */
-
 public ReferenceBinding superclass() {
 	if ((this.tagBits & HasUnresolvedSuperclass) == 0)
 		return this.superclass;
@@ -774,7 +772,6 @@
 	return this.superclass;
 }
 // NOTE: superInterfaces of binary types are resolved when needed
-
 public ReferenceBinding[] superInterfaces() {
 	if ((this.tagBits & HasUnresolvedSuperinterfaces) == 0)
 		return this.superInterfaces;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
index 45e7a6f..389003f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,13 +23,16 @@
 	public static final int PACKAGE = ASTNode.Bit5;
 	public static final int IMPORT = ASTNode.Bit6;
 	public static final int ARRAY_TYPE = TYPE | ASTNode.Bit7;
-	public static final int PARAMETERIZED_TYPE = TYPE | ASTNode.Bit8;
-	public static final int WILDCARD_TYPE = TYPE | ASTNode.Bit9;
-	public static final int RAW_TYPE = TYPE | ASTNode.Bit10;
-	public static final int GENERIC_TYPE = TYPE | ASTNode.Bit11;
-	public static final int TYPE_PARAMETER = TYPE | ASTNode.Bit12;
-	public static final int ANNOTATION_BINDING = TYPE | ASTNode.Bit13; // for annotation refs
-
+	public static final int BASE_TYPE = TYPE | ASTNode.Bit8;
+	public static final int PARAMETERIZED_TYPE = TYPE | ASTNode.Bit9;
+	public static final int WILDCARD_TYPE = TYPE | ASTNode.Bit10;
+	public static final int RAW_TYPE = TYPE | ASTNode.Bit11;
+	public static final int GENERIC_TYPE = TYPE | ASTNode.Bit12;
+	public static final int TYPE_PARAMETER = TYPE | ASTNode.Bit13;
+	
+	// TODO (jerome) change to true to fix https://bugs.eclipse.org/bugs/show_bug.cgi?id=90392
+	public static boolean USE_ACCESS_FLAGS_IN_BINDING_KEY = false;
+	
 	/* API
 	* Answer the receiver's binding type from Binding.BindingID.
 	*
@@ -42,6 +45,13 @@
 	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
 	 */
 	public char[] computeUniqueKey() {
+		return computeUniqueKey(USE_ACCESS_FLAGS_IN_BINDING_KEY/*without access flags*/);
+	}
+	/*
+	 * Computes a key that uniquely identifies this binding. Optinaly include access flags.
+	 * Returns null if binding is not a TypeBinding, a MethodBinding, a FieldBinding or a PackageBinding.
+	 */
+	public char[] computeUniqueKey(boolean withAccessFlags) {
 		return null;
 	}
 	
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index 50a15c7..4562dac 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -37,7 +37,7 @@
 	public int subscopeCount = 0; // need access from code assist
 
 	// record the current case statement being processed (for entire switch case block).
-	public CaseStatement switchCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
+	public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
 
 	protected BlockScope(int kind, Scope parent) {
 
@@ -279,9 +279,11 @@
 	 */
 	public void emulateOuterAccess(LocalVariableBinding outerLocalVariable) {
 
-		MethodScope currentMethodScope;
-		if ((currentMethodScope = this.methodScope())
-			!= outerLocalVariable.declaringScope.methodScope()) {
+		BlockScope outerVariableScope = outerLocalVariable.declaringScope;
+		if (outerVariableScope == null)
+			return; // no need to further emulate as already inserted (val$this$0)
+		MethodScope currentMethodScope = this.methodScope();
+		if (outerVariableScope.methodScope() != currentMethodScope) {
 			NestedTypeBinding currentType = (NestedTypeBinding) this.enclosingSourceType();
 
 			//do nothing for member types, pre emulation was performed already
@@ -323,7 +325,11 @@
 			if (subscopes[i] instanceof ClassScope) {
 				LocalTypeBinding sourceType = (LocalTypeBinding)((ClassScope) subscopes[i]).referenceContext.binding;
 				// from 1.4 on, local types should not be accessed across switch case blocks (52221)				
-				if (compliance >= ClassFileConstants.JDK1_4 && sourceType.switchCase != this.switchCase) continue;
+				if (compliance >= ClassFileConstants.JDK1_4 && sourceType.enclosingCase != null) {
+					if (!this.isInsideCase(sourceType.enclosingCase)) {
+						continue;
+					}
+				}
 				if (CharOperation.equals(sourceType.sourceName(), name))
 					return sourceType;
 			}
@@ -595,7 +601,8 @@
 		SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType();
 
 		// identity check
-		if (currentMethodScope == outerLocalVariable.declaringScope.methodScope()) {
+		BlockScope variableScope = outerLocalVariable.declaringScope;
+		if (variableScope == null /*val$this$0*/ || currentMethodScope == variableScope.methodScope()) {
 			return new VariableBinding[] { outerLocalVariable };
 			// implicit this is good enough
 		}
@@ -631,13 +638,13 @@
 	public Object[] getEmulationPath(
 			ReferenceBinding targetEnclosingType, 
 			boolean onlyExactMatch,
-			boolean ignoreEnclosingArgInConstructorCall) {
+			boolean denyEnclosingArgInConstructorCall) {
 				
 		MethodScope currentMethodScope = this.methodScope();
 		SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType();
 
 		// use 'this' if possible
-		if (!currentMethodScope.isConstructorCall && !currentMethodScope.isStatic) {
+		if (!currentMethodScope.isStatic && !currentMethodScope.isConstructorCall) {
 			if (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeErasingTo(targetEnclosingType) != null)) {
 				return EmulationPathToImplicitThis; // implicit this is good enough
 			}
@@ -656,7 +663,7 @@
 			SyntheticArgumentBinding syntheticArg;
 			if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(targetEnclosingType, onlyExactMatch)) != null) {
 				// reject allocation and super constructor call
-				if (ignoreEnclosingArgInConstructorCall 
+				if (denyEnclosingArgInConstructorCall
 						&& currentMethodScope.isConstructorCall 
 						&& (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeErasingTo(targetEnclosingType) != null))) {
 					return NoEnclosingInstanceInConstructorCall;
@@ -669,6 +676,20 @@
 		if (currentMethodScope.isStatic) {
 			return NoEnclosingInstanceInStaticContext;
 		}
+		if (sourceType.isAnonymousType()) {
+			ReferenceBinding enclosingType = sourceType.enclosingType();
+			if (enclosingType.isNestedType()) {
+				NestedTypeBinding nestedEnclosingType = (NestedTypeBinding) enclosingType;
+				SyntheticArgumentBinding enclosingArgument = nestedEnclosingType.getSyntheticArgument(nestedEnclosingType.enclosingType(), onlyExactMatch);
+				if (enclosingArgument != null) {
+					FieldBinding syntheticField = sourceType.getSyntheticField(enclosingArgument);
+					if (syntheticField != null) {
+						if (syntheticField.type == targetEnclosingType || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeErasingTo(targetEnclosingType) != null))
+							return new Object[] { syntheticField };
+					}
+				}
+			}
+		}
 		FieldBinding syntheticField = sourceType.getSyntheticField(targetEnclosingType, onlyExactMatch);
 		if (syntheticField != null) {
 			if (currentMethodScope.isConstructorCall){
@@ -676,6 +697,7 @@
 			}
 			return new Object[] { syntheticField };
 		}
+
 		// could be reached through a sequence of enclosing instance link (nested members)
 		Object[] path = new Object[2]; // probably at least 2 of them
 		ReferenceBinding currentType = sourceType.enclosingType();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
new file mode 100644
index 0000000..49db10a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.lookup;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+public class CaptureBinding extends TypeVariableBinding {
+	
+	public TypeBinding lowerBound;
+	public WildcardBinding wildcard;
+	
+	public CaptureBinding(WildcardBinding wildcard) {
+		super(WILDCARD_CAPTURE_NAME, null, 0);
+		this.wildcard = wildcard;
+		this.modifiers = AccPublic | AccGenericSignature; // treat capture as public
+		this.fPackage = wildcard.fPackage;
+		
+		TypeVariableBinding wildcardVariable = wildcard.typeVariable();
+		switch (wildcard.boundKind) {
+			case Wildcard.EXTENDS :
+				this.superclass = wildcard.superclass();
+				this.firstBound = wildcard.bound;
+				ReferenceBinding[] wildcardInterfaces = wildcard.superInterfaces();
+				if (wildcardInterfaces == NoSuperInterfaces) {
+					this.superInterfaces = NoSuperInterfaces;
+				} else {
+					this.superInterfaces = Scope.greaterLowerBound(wildcardInterfaces);
+				}
+				if ((wildcard.bound.tagBits & HasTypeVariable) == 0)
+					this.tagBits &= ~HasTypeVariable;
+				break;
+			case Wildcard.UNBOUND :
+				this.superclass = wildcardVariable.superclass();
+				this.superInterfaces = wildcardVariable.superInterfaces();
+				this.tagBits &= ~HasTypeVariable;
+				break;
+			case Wildcard.SUPER :
+				this.superclass = wildcardVariable.superclass();
+				if (wildcardVariable.firstBound == this.superclass || wildcard.bound == this.superclass) {
+					this.firstBound = this.superclass;
+				}
+				this.superInterfaces = wildcardVariable.superInterfaces();
+				this.lowerBound = wildcard.bound;
+				if ((wildcard.bound.tagBits & HasTypeVariable) == 0)
+					this.tagBits &= ~HasTypeVariable;
+				break;
+		}
+	}
+
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+		return CharOperation.concat(WILDCARD_CAPTURE, this.wildcard.computeUniqueKey(withAccessFlags));
+	}	
+
+	public String debugName() {
+		if (this.wildcard != null) {
+			return String.valueOf(TypeConstants.WILDCARD_CAPTURE_NAME) + this.wildcard.debugName(); //$NON-NLS-1$
+		}
+		return super.debugName();
+	}
+	
+	public char[] genericTypeSignature() {
+		if (this.genericTypeSignature == null) {
+			this.genericTypeSignature = CharOperation.concat(WILDCARD_CAPTURE, this.wildcard.genericTypeSignature());
+		}
+		return this.genericTypeSignature;
+	}
+	
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isCapture()
+	 */
+	public boolean isCapture() {
+		return true;
+	}
+	
+	/**
+	 * @see TypeBinding#isEquivalentTo(TypeBinding)
+	 */
+	public boolean isEquivalentTo(TypeBinding otherType) {
+	    if (this == otherType) return true;
+	    if (otherType == null) return false;
+		// capture of ? extends X[]
+		if (this.firstBound != null && this.firstBound.isArrayType()) {
+			if (this.firstBound.isCompatibleWith(otherType))
+				return true;
+		}
+	    if (otherType.isWildcard()) // wildcard
+			return ((WildcardBinding) otherType).boundCheck(this);
+		return false;
+	}
+
+	public char[] readableName() {
+		if (this.wildcard != null) {
+			return CharOperation.concat(TypeConstants.WILDCARD_CAPTURE_NAME, this.wildcard.readableName());
+		}
+		return super.readableName();
+	}
+	
+	public char[] shortReadableName() {
+		if (this.wildcard != null) {
+			return CharOperation.concat(TypeConstants.WILDCARD_CAPTURE_NAME, this.wildcard.shortReadableName());
+		}
+		return super.shortReadableName();
+	}
+	
+	public String toString() {
+		if (this.wildcard != null) {
+			return String.valueOf(TypeConstants.WILDCARD_CAPTURE_NAME) + this.wildcard.toString();
+		}
+		return super.toString();
+	}		
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 82bda2d..b24595d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -164,7 +164,7 @@
 		referenceContext.initializerScope = new MethodScope(this, referenceContext, false);
 
 		// build the binding or the local type
-		LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, this.switchCase());
+		LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, this.innermostSwitchCase());
 		referenceContext.binding = localType;
 		checkAndSetModifiers();
 		buildTypeVariables();
@@ -230,7 +230,7 @@
 				TypeDeclaration memberContext = referenceContext.memberTypes[i];
 				if (memberContext.kind() == IGenericType.INTERFACE_DECL
 					&& sourceType.isNestedType()
-					&& sourceType.isClass()
+					&& sourceType.isClass() // no need to check for enum, since implicitly static
 					&& !sourceType.isStatic()) {
 					problemReporter().nestedClassCannotDeclareInterface(memberContext);
 					continue nextMember;
@@ -301,7 +301,6 @@
 			System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[count], 0, count);
 
 		referenceContext.binding.methods = methodBindings;
-		referenceContext.binding.modifiers |= AccUnresolved; // until methods() is sent
 	}
 	
 	SourceTypeBinding buildType(SourceTypeBinding enclosingType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
@@ -354,27 +353,31 @@
 		int modifiers = sourceType.modifiers;
 		if ((modifiers & AccAlternateModifierProblem) != 0)
 			problemReporter().duplicateModifierForType(sourceType);
-
 		ReferenceBinding enclosingType = sourceType.enclosingType();
 		boolean isMemberType = sourceType.isMemberType();
-		
 		if (isMemberType) {
 			// checks for member types before local types to catch local members
 			if (enclosingType.isStrictfp())
 				modifiers |= AccStrictfp;
-			if (enclosingType.isViewedAsDeprecated() && !sourceType.isDeprecated())
-				modifiers |= AccDeprecatedImplicitly;
-			if ((enclosingType.modifiers & AccInterface) != 0)
+			if (enclosingType.isInterface())
 				modifiers |= AccPublic;
-			if (sourceType.isEnum())
-				modifiers |= AccStatic;
+			if (sourceType.isEnum()) {
+				if (!enclosingType.isStatic())
+					problemReporter().nonStaticContextForEnumMemberType(sourceType);
+				else
+					modifiers |= AccStatic;
+			}
 		} else if (sourceType.isLocalType()) {
+			if (sourceType.isEnum()) {
+				problemReporter().illegalLocalTypeDeclaration(referenceContext);
+				sourceType.modifiers = 0;
+				return;
+			}
 			if (sourceType.isAnonymousType()) {
 			    modifiers |= AccFinal;
 			    // set AccEnum flag for anonymous body of enum constants
-			    if (referenceContext.allocation.type == null) {
+			    if (referenceContext.allocation.type == null)
 			    	modifiers |= AccEnum;
-			    }
 			}
 			Scope scope = this;
 			do {
@@ -387,9 +390,8 @@
 							// inside field declaration ? check field modifier to see if deprecated
 							if (methodScope.initializedField != null) {
 									// currently inside this field initialization
-								if (methodScope.initializedField.isViewedAsDeprecated() && !sourceType.isDeprecated()){
+								if (methodScope.initializedField.isViewedAsDeprecated() && !sourceType.isDeprecated())
 									modifiers |= AccDeprecatedImplicitly;
-								}
 							} else {
 								if (type.isStrictfp())
 									modifiers |= AccStrictfp;
@@ -398,7 +400,7 @@
 							}					
 						} else {
 							MethodBinding method = ((AbstractMethodDeclaration) methodScope.referenceContext).binding;
-							if (method != null){
+							if (method != null) {
 								if (method.isStrictfp())
 									modifiers |= AccStrictfp;
 								if (method.isViewedAsDeprecated() && !sourceType.isDeprecated())
@@ -417,6 +419,7 @@
 				scope = scope.parent;
 			} while (scope != null);
 		}
+
 		// after this point, tests on the 16 bits reserved.
 		int realModifiers = modifiers & AccJustFlag;
 
@@ -426,11 +429,10 @@
 				int unexpectedModifiers =
 					~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccInterface | AccStrictfp | AccAnnotation);
 				if ((realModifiers & unexpectedModifiers) != 0) {
-					if ((realModifiers & AccAnnotation) != 0) {
+					if ((realModifiers & AccAnnotation) != 0)
 						problemReporter().illegalModifierForAnnotationMemberType(sourceType);
-					} else {
+					else
 						problemReporter().illegalModifierForMemberInterface(sourceType);
-					}
 				}
 				/*
 				} else if (sourceType.isLocalType()) { //interfaces cannot be defined inside a method
@@ -441,22 +443,20 @@
 			} else {
 				int unexpectedModifiers = ~(AccPublic | AccAbstract | AccInterface | AccStrictfp | AccAnnotation);
 				if ((realModifiers & unexpectedModifiers) != 0) {
-					if ((realModifiers & AccAnnotation) != 0) {
+					if ((realModifiers & AccAnnotation) != 0)
 						problemReporter().illegalModifierForAnnotationType(sourceType);
-					} else {
+					else
 						problemReporter().illegalModifierForInterface(sourceType);
-					}
 				}
 			}
 			modifiers |= AccAbstract;
 		} else if ((realModifiers & AccEnum) != 0) {
 			// detect abnormal cases for enums
 			if (isMemberType) { // includes member types defined inside local types
-				int unexpectedModifiers =
-					~(AccPublic | AccPrivate | AccProtected | AccStatic | AccStrictfp | AccEnum);
+				int unexpectedModifiers = ~(AccPublic | AccPrivate | AccProtected | AccStatic | AccStrictfp | AccEnum);
 				if ((realModifiers & unexpectedModifiers) != 0)
 					problemReporter().illegalModifierForMemberEnum(sourceType);
-			} else if (sourceType.isLocalType()) {
+			} else if (sourceType.isLocalType()) { // each enum constant is an anonymous local type
 				int unexpectedModifiers = ~(AccStrictfp | AccFinal | AccEnum); // add final since implicitly set for anonymous type
 				if ((realModifiers & unexpectedModifiers) != 0)
 					problemReporter().illegalModifierForLocalEnum(sourceType);
@@ -465,15 +465,14 @@
 				if ((realModifiers & unexpectedModifiers) != 0)
 					problemReporter().illegalModifierForEnum(sourceType);
 			}
-			if ((referenceContext.bits & ASTNode.HasAbstractMethods) != 0) {
+
+// what about inherited interface methods?
+			if ((referenceContext.bits & ASTNode.HasAbstractMethods) != 0)
 				modifiers |= AccAbstract;
-			}
-			
 		} else {
 			// detect abnormal cases for classes
 			if (isMemberType) { // includes member types defined inside local types
-				int unexpectedModifiers =
-					~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccFinal | AccStrictfp);
+				int unexpectedModifiers = ~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccFinal | AccStrictfp);
 				if ((realModifiers & unexpectedModifiers) != 0)
 					problemReporter().illegalModifierForMemberClass(sourceType);
 			} else if (sourceType.isLocalType()) {
@@ -508,16 +507,15 @@
 				if ((accessorBits & (accessorBits - 1)) > 1) {
 					problemReporter().illegalVisibilityModifierCombinationForMemberType(sourceType);
 
-					// need to keep the less restrictive
+					// need to keep the less restrictive so disable Protected/Private as necessary
 					if ((accessorBits & AccPublic) != 0) {
 						if ((accessorBits & AccProtected) != 0)
 							modifiers &= ~AccProtected;
 						if ((accessorBits & AccPrivate) != 0)
 							modifiers &= ~AccPrivate;
+					} else if ((accessorBits & AccProtected) != 0 && (accessorBits & AccPrivate) != 0) {
+						modifiers &= ~AccPrivate;
 					}
-					if ((accessorBits & AccProtected) != 0)
-						if ((accessorBits & AccPrivate) != 0)
-							modifiers &= ~AccPrivate;
 				}
 			}
 
@@ -525,10 +523,9 @@
 			if ((realModifiers & AccStatic) == 0) {
 				if (enclosingType.isInterface())
 					modifiers |= AccStatic;
-			} else {
-				if (!enclosingType.isStatic())
-					// error the enclosing type of a static field must be static or a top-level type
-					problemReporter().illegalStaticModifierForMemberType(sourceType);
+			} else if (!enclosingType.isStatic()) {
+				// error the enclosing type of a static field must be static or a top-level type
+				problemReporter().illegalStaticModifierForMemberType(sourceType);
 			}
 		}
 
@@ -544,28 +541,28 @@
 	*/
 	private void checkAndSetModifiersForField(FieldBinding fieldBinding, FieldDeclaration fieldDecl) {
 		int modifiers = fieldBinding.modifiers;
+		final ReferenceBinding declaringClass = fieldBinding.declaringClass;
 		if ((modifiers & AccAlternateModifierProblem) != 0)
-			problemReporter().duplicateModifierForField(fieldBinding.declaringClass, fieldDecl);
+			problemReporter().duplicateModifierForField(declaringClass, fieldDecl);
 
-		if ((fieldBinding.declaringClass.modifiers  & AccInterface) != 0) {
+		if (declaringClass.isInterface()) {
 			int expectedValue = AccPublic | AccStatic | AccFinal;
 			// set the modifiers
 			modifiers |= expectedValue;
 
 			// and then check that they are the only ones
 			if ((modifiers & AccJustFlag) != expectedValue) {
-				if ((fieldBinding.declaringClass.modifiers  & AccAnnotation) != 0) {
+				if ((declaringClass.modifiers  & AccAnnotation) != 0)
 					problemReporter().illegalModifierForAnnotationField(fieldDecl);
-				} else {
+				else
 					problemReporter().illegalModifierForInterfaceField(fieldDecl);
-				}
 			}
 			fieldBinding.modifiers = modifiers;
 			return;
 		} else if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
 			// check that they are not modifiers in source
 			if ((modifiers & AccJustFlag) != 0)
-				problemReporter().illegalModifierForEnumConstant(fieldBinding.declaringClass, fieldDecl);
+				problemReporter().illegalModifierForEnumConstant(declaringClass, fieldDecl);
 		
 			// set the modifiers
 			int implicitValue = AccPublic | AccStatic | AccFinal | AccEnum;
@@ -575,37 +572,32 @@
 
 		// after this point, tests on the 16 bits reserved.
 		int realModifiers = modifiers & AccJustFlag;
-		int unexpectedModifiers =
-			~(AccPublic | AccPrivate | AccProtected | AccFinal | AccStatic | AccTransient | AccVolatile);
-		if ((realModifiers & unexpectedModifiers) != 0)
-			problemReporter().illegalModifierForField(fieldBinding.declaringClass, fieldDecl);
+		int unexpectedModifiers = ~(AccPublic | AccPrivate | AccProtected | AccFinal | AccStatic | AccTransient | AccVolatile);
+		if ((realModifiers & unexpectedModifiers) != 0) {
+			problemReporter().illegalModifierForField(declaringClass, fieldDecl);
+			modifiers &= ~AccJustFlag | ~unexpectedModifiers;
+		}
 
 		int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate);
 		if ((accessorBits & (accessorBits - 1)) > 1) {
-			problemReporter().illegalVisibilityModifierCombinationForField(
-				fieldBinding.declaringClass,
-				fieldDecl);
+			problemReporter().illegalVisibilityModifierCombinationForField(declaringClass, fieldDecl);
 
-			// need to keep the less restrictive
+			// need to keep the less restrictive so disable Protected/Private as necessary
 			if ((accessorBits & AccPublic) != 0) {
 				if ((accessorBits & AccProtected) != 0)
 					modifiers &= ~AccProtected;
 				if ((accessorBits & AccPrivate) != 0)
 					modifiers &= ~AccPrivate;
+			} else if ((accessorBits & AccProtected) != 0 && (accessorBits & AccPrivate) != 0) {
+				modifiers &= ~AccPrivate;
 			}
-			if ((accessorBits & AccProtected) != 0)
-				if ((accessorBits & AccPrivate) != 0)
-					modifiers &= ~AccPrivate;
 		}
 
 		if ((realModifiers & (AccFinal | AccVolatile)) == (AccFinal | AccVolatile))
-			problemReporter().illegalModifierCombinationFinalVolatileForField(
-				fieldBinding.declaringClass,
-				fieldDecl);
+			problemReporter().illegalModifierCombinationFinalVolatileForField(declaringClass, fieldDecl);
 
-		if (fieldDecl.initialization == null && (modifiers & AccFinal) != 0) {
+		if (fieldDecl.initialization == null && (modifiers & AccFinal) != 0)
 			modifiers |= AccBlankFinal;
-		}
 		fieldBinding.modifiers = modifiers;
 	}
 
@@ -689,9 +681,11 @@
 
 	private void connectMemberTypes() {
 		SourceTypeBinding sourceType = referenceContext.binding;
-		if (sourceType.memberTypes != NoMemberTypes)
-			for (int i = 0, size = sourceType.memberTypes.length; i < size; i++)
-				 ((SourceTypeBinding) sourceType.memberTypes[i]).scope.connectTypeHierarchy();
+		ReferenceBinding[] memberTypes = sourceType.memberTypes;
+		if (memberTypes != null && memberTypes != NoMemberTypes) {
+			for (int i = 0, size = memberTypes.length; i < size; i++)
+				 ((SourceTypeBinding) memberTypes[i]).scope.connectTypeHierarchy();
+		}
 	}
 	/*
 		Our current belief based on available JCK tests is:
@@ -765,7 +759,7 @@
 		ParameterizedTypeBinding  superType = createParameterizedType(rootEnumType, new TypeBinding[]{ sourceType } , null);
 		sourceType.superclass = superType;
 		// bound check
-		if (!refTypeVariables[0].boundCheck(superType, sourceType)) {
+		if (refTypeVariables[0].boundCheck(superType, sourceType) != TypeConstants.OK) {
 			problemReporter().typeMismatchError(rootEnumType, refTypeVariables[0], sourceType, null);
 		}
 		return !foundCycle;
@@ -811,9 +805,8 @@
 			superInterfaceRef.resolvedType = superInterface; // hold onto the problem type
 			// Check for a duplicate interface once the name is resolved, otherwise we may be confused (ie : a.b.I and c.d.I)
 			for (int k = 0; k < count; k++) {
-				if (interfaceBindings[k] == superInterface) {
-					// should this be treated as a warning?
-					problemReporter().duplicateSuperinterface(sourceType, referenceContext, superInterface);
+				if (interfaceBindings[k].erasure() == superInterface.erasure()) {
+					problemReporter().duplicateSuperinterface(sourceType, referenceContext, (ReferenceBinding) superInterface.erasure());
 					continue nextInterface;
 				}
 			}
@@ -822,6 +815,8 @@
 				sourceType.tagBits |= HierarchyHasProblems;
 				noProblems = false;
 				continue nextInterface;
+			} else if (superInterface.isAnnotationType()){
+				problemReporter().annotationTypeUsedAsSuperinterface(sourceType, superInterfaceRef, superInterface);
 			}
 			if ((superInterface.tagBits & TagBits.HasDirectWildcard) != 0) {
 				problemReporter().superTypeCannotUseWildcard(sourceType, superInterfaceRef, superInterface);
@@ -858,9 +853,9 @@
 		SourceTypeBinding sourceType = referenceContext.binding;
 		if ((sourceType.tagBits & BeginHierarchyCheck) == 0) {
 			sourceType.tagBits |= BeginHierarchyCheck;
-			boolean noProblems = connectTypeVariables(referenceContext.typeParameters);
-			noProblems &= connectSuperclass();
+			boolean noProblems = connectSuperclass();
 			noProblems &= connectSuperInterfaces();
+			noProblems &= connectTypeVariables(referenceContext.typeParameters);
 			sourceType.tagBits |= EndHierarchyCheck;
 			if (noProblems && sourceType.isHierarchyInconsistent())
 				problemReporter().hierarchyHasProblems(sourceType);
@@ -892,26 +887,14 @@
 			return;
 
 		sourceType.tagBits |= BeginHierarchyCheck;
-		boolean noProblems = connectTypeVariables(referenceContext.typeParameters);
-		noProblems &= connectSuperclass();
+		boolean noProblems = connectSuperclass();
 		noProblems &= connectSuperInterfaces();
+		noProblems &= connectTypeVariables(referenceContext.typeParameters);
 		sourceType.tagBits |= EndHierarchyCheck;
 		if (noProblems && sourceType.isHierarchyInconsistent())
 			problemReporter().hierarchyHasProblems(sourceType);
 	}
 
-	public boolean detectAnnotationCycle(TypeBinding sourceType, TypeBinding annotationElementType, TypeReference reference) {
-		if (!annotationElementType.isAnnotationType()) 
-			return false;
-
-		if (sourceType == annotationElementType) {
-			problemReporter().annotationCircularity(sourceType, annotationElementType, reference);
-			return true;
-		}
-		// TODO (kent) add support for detecting indirect cases using TagBits.BeginAnnotationCheck/EndAnnotationCheck
-		return false;
-	}
-
 	public boolean detectHierarchyCycle(TypeBinding superType, TypeReference reference, TypeBinding[] argTypes) {
 		if (!(superType instanceof ReferenceBinding)) return false;
 
@@ -970,14 +953,14 @@
 			//		- a binary type... this case MUST be caught & reported here
 			//		- another source type... this case is reported against the other source type
 			boolean hasCycle = false;
-			if (superType.superclass() != null) {
-				if (sourceType == superType.superclass()) {
+			ReferenceBinding parentType = superType.superclass();
+			if (parentType != null) {
+				if (sourceType == parentType) {
 					problemReporter().hierarchyCircularity(sourceType, superType, reference);
 					sourceType.tagBits |= HierarchyHasProblems;
 					superType.tagBits |= HierarchyHasProblems;
 					return true;
 				}
-				ReferenceBinding parentType = superType.superclass();
 				if (parentType.isParameterizedType())
 					parentType = ((ParameterizedTypeBinding) parentType).type;
 				hasCycle |= detectHierarchyCycle(sourceType, parentType, reference);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index 9033073..56b966b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -113,7 +113,7 @@
 			if ((mainTypeName = referenceContext.getMainTypeName()) != null // mainTypeName == null means that implementor of ICompilationUnit decided to return null
 					&& !CharOperation.equals(mainTypeName, typeDecl.name)) {
 				problemReporter().publicClassMustMatchFileName(referenceContext, typeDecl);
-				continue nextType;
+				// tolerate faulty main type name (91091), allow to proceed into type construction
 			}
 		}
 
@@ -336,6 +336,17 @@
 					continue nextImport;
 				}
 				typesBySimpleNames.put(compoundName[compoundName.length - 1], referenceBinding);
+			} else if (importBinding instanceof FieldBinding) {
+				for (int j = 0; j < index; j++) {
+					ImportBinding resolved = resolvedImports[j];
+					// find other static fields with the same name
+					if (resolved.isStatic() && resolved.resolvedImport instanceof FieldBinding && importBinding != resolved.resolvedImport) {
+						if (CharOperation.equals(compoundName[compoundName.length - 1], resolved.compoundName[resolved.compoundName.length - 1])) {
+							problemReporter().duplicateImport(importReference);
+							continue nextImport;
+						}
+					}
+				}
 			}
 			resolvedImports[index++] = new ImportBinding(compoundName, false, importBinding, importReference);
 		}
@@ -438,9 +449,13 @@
 	// look to see if its a static field first
 	ReferenceBinding type = (ReferenceBinding) binding;
 	FieldBinding field = findField(type, name, null, true);
-	if (field != null && field.isStatic() && field.canBeSeenBy(fPackage))
+	if (field != null && field.isValidBinding() && field.isStatic() && field.canBeSeenBy(fPackage))
 		return field;
 
+	// look to see if there is a static method with the same selector
+	MethodBinding method = findStaticMethod(type, name);
+	if (method != null) return method;
+
 	type = findMemberType(name, type);
 	if (type == null || !type.isStatic())
 		return new ProblemReferenceBinding(compoundName, type, NotFound);
@@ -448,6 +463,24 @@
 		return new ProblemReferenceBinding(compoundName, type, NotVisible);
 	return type;
 }
+MethodBinding findStaticMethod(ReferenceBinding currentType, char[] selector) {
+	if (!currentType.canBeSeenBy(this))
+		return null;
+
+	do {
+		MethodBinding[] methods = currentType.getMethods(selector);
+		if (methods != NoMethods) {
+			for (int i = methods.length; --i >= 0;) {
+				MethodBinding method = methods[i];
+				if (method.isStatic() && method.canBeSeenBy(fPackage))
+					return method;
+			}
+		}
+		if (currentType.superInterfaces() == null) // needed for statically imported types which don't know their hierarchy yet
+			((SourceTypeBinding) currentType).scope.connectTypeHierarchy();
+	} while ((currentType = currentType.superclass()) != null);
+	return null;
+}
 ImportBinding[] getDefaultImports() {
 	// initialize the default imports if necessary... share the default java.lang.* import
 	if (environment.defaultImports != null) return environment.defaultImports;
@@ -647,6 +680,7 @@
 		type = ((ArrayBinding) type).leafComponentType;
 
 	switch (type.kind()) {
+		case Binding.BASE_TYPE :
 		case Binding.TYPE_PARAMETER :
 		case Binding.WILDCARD_TYPE :
 			return null;
@@ -654,12 +688,9 @@
 		case Binding.RAW_TYPE :
 			type = type.erasure();
 	}
-
-	if (type instanceof ReferenceBinding) {
-		ReferenceBinding refType = (ReferenceBinding) type;
-		if (!refType.isLocalType()) return refType;
-	}
-	return null;
+	ReferenceBinding refType = (ReferenceBinding) type;
+	if (refType.isLocalType()) return null;
+	return refType;
 }
 public void verifyMethods(MethodVerifier verifier) {
 	for (int i = 0, length = topLevelTypes.length; i < length; i++)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java
index f8e80f1..395a1a5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilerModifiers.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,9 +16,7 @@
 public interface CompilerModifiers extends ClassFileConstants { // modifier constant
 	// those constants are depending upon ClassFileConstants (relying that classfiles only use the 16 lower bits)
 	final int AccDefault = 0;
-	final int AccJustFlag = // 16 lower bits
-	    	ASTNode.Bit1|ASTNode.Bit2|ASTNode.Bit3|ASTNode.Bit4|ASTNode.Bit5|ASTNode.Bit6|ASTNode.Bit7|ASTNode.Bit8|
-			ASTNode.Bit9|ASTNode.Bit10|ASTNode.Bit11|ASTNode.Bit12|ASTNode.Bit13|ASTNode.Bit14|ASTNode.Bit15|ASTNode.Bit16;
+	final int AccJustFlag = 0xFFFF;// 16 lower bits
 
 	// bit17 - free
 	// bit18 - IConstants.AccAnnotationDefault
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
index 5a01f8b..2dcd27a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,11 +25,6 @@
 public FieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant) {
 	super(name, type, modifiers, constant);
 	this.declaringClass = declaringClass;
-
-	// propagate the deprecated modifier
-	if (this.declaringClass != null)
-		if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated())
-			this.modifiers |= AccDeprecatedImplicitly;
 }
 public FieldBinding(FieldDeclaration field, TypeBinding type, int modifiers, ReferenceBinding declaringClass) {
 	this(field.name, type, modifiers, declaringClass, null);
@@ -82,8 +77,10 @@
 		
 		ReferenceBinding currentType = invocationType;
 		int depth = 0;
+		ReferenceBinding receiverErasure = (ReferenceBinding)receiverType.erasure();
+		ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure();
 		do {
-			if (declaringClass.isSuperclassOf(currentType)) {
+			if (currentType.findSuperTypeErasingTo(declaringErasure) != null) {
 				if (invocationSite.isSuperAccess()){
 					return true;
 				}
@@ -95,7 +92,7 @@
 					if (depth > 0) invocationSite.setDepth(depth);
 					return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
 				}
-				if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){
+				if (currentType == receiverErasure || receiverErasure.findSuperTypeErasingTo(currentType) != null){
 					if (depth > 0) invocationSite.setDepth(depth);
 					return true;
 				}
@@ -154,17 +151,43 @@
 }
 /*
  * declaringUniqueKey dot fieldName
- * p.X { X<T> x} --> Lp/X;.x;
+ * p.X { X<T> x} --> Lp/X;.x^123
  */
-public char[] computeUniqueKey() {
-	char[] declaringKey = this.declaringClass == null /*case of length field for an array*/ ? CharOperation.NO_CHAR : this.declaringClass.computeUniqueKey();
+public char[] computeUniqueKey(boolean withAccessFlags) {
+	// declaring key
+	char[] declaringKey = 
+		this.declaringClass == null /*case of length field for an array*/ 
+			? CharOperation.NO_CHAR 
+			: this.declaringClass.computeUniqueKey(false/*without access flags*/);
 	int declaringLength = declaringKey.length;
+	
+	// name
 	int nameLength = this.name.length;
-	char[] uniqueKey = new char[declaringLength + 1 + nameLength];
-	System.arraycopy(declaringKey, 0, uniqueKey, 0, declaringLength);
-	uniqueKey[declaringLength] = '.';
-	System.arraycopy(this.name, 0, uniqueKey, declaringLength + 1, nameLength);
-	return uniqueKey;
+	
+	if (withAccessFlags) {
+		// flags
+		String flags = Integer.toString(getAccessFlags());
+		int flagsLength = flags.length();
+	
+		char[] uniqueKey = new char[declaringLength + 1 + nameLength + 1 + flagsLength];
+		int index = 0;
+		System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+		index += declaringLength;
+		uniqueKey[index++] = '.';
+		System.arraycopy(this.name, 0, uniqueKey, index, nameLength);
+		index += nameLength;
+		uniqueKey[index++] = '^';
+		flags.getChars(0, flagsLength, uniqueKey, index);
+		return uniqueKey;
+	} else {
+		char[] uniqueKey = new char[declaringLength + 1 + nameLength];
+		int index = 0;
+		System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+		index += declaringLength;
+		uniqueKey[index++] = '.';
+		System.arraycopy(this.name, 0, uniqueKey, index, nameLength);
+		return uniqueKey;
+	}
 }
 /**
  * X<T> t   -->  LX<TT;>;
@@ -188,7 +211,8 @@
 	if ((originalField.tagBits & TagBits.AnnotationResolved) == 0 && originalField.declaringClass instanceof SourceTypeBinding) {
 		TypeDeclaration typeDecl = ((SourceTypeBinding)originalField.declaringClass).scope.referenceContext;
 		FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
-		ASTNode.resolveAnnotations(isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope, fieldDecl.annotations, originalField);
+		if (fieldDecl != null)
+			ASTNode.resolveAnnotations(isStatic() ? typeDecl.staticInitializerScope : typeDecl.initializerScope, fieldDecl.annotations, originalField);
 	}
 	return originalField.tagBits;
 }
@@ -251,8 +275,7 @@
 */
 
 public final boolean isViewedAsDeprecated() {
-	return (modifiers & AccDeprecated) != 0 ||
-		(modifiers & AccDeprecatedImplicitly) != 0;
+	return (modifiers & (AccDeprecated | AccDeprecatedImplicitly)) != 0;
 }
 /* Answer true if the receiver is a volatile field
 */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java
index 05c2992..3017a5f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java
index e722789..33947ba 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
index 462f95e..ffcf9d7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
index 541448f..c96f153 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java
@@ -1,16 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 
@@ -19,7 +20,9 @@
 
 	private InnerEmulationDependency[] dependents;
 	public ArrayBinding[] localArrayBindings; // used to cache array bindings of various dimensions for this local type
-	public CaseStatement switchCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
+	public CaseStatement enclosingCase; // from 1.4 on, local types should not be accessed across switch case blocks (52221)
+	int sourceStart; // used by computeUniqueKey to uniquely identify this binding
+	public MethodBinding enclosingMethod;
 	
 public LocalTypeBinding(ClassScope scope, SourceTypeBinding enclosingType, CaseStatement switchCase) {
 	super(
@@ -31,7 +34,13 @@
 		this.tagBits |= AnonymousTypeMask;
 	else
 		this.tagBits |= LocalTypeMask;
-	this.switchCase = switchCase;
+	this.enclosingCase = switchCase;
+	this.sourceStart = scope.referenceContext.sourceStart;
+	MethodScope methodScope = scope.enclosingMethodScope();
+	AbstractMethodDeclaration declaration = methodScope.referenceMethod();
+	if (declaration != null) {
+		this.enclosingMethod = declaration.binding;
+	}
 }
 /* Record a dependency onto a source target type which may be altered
 * by the end of the innerclass emulation. Later on, we will revisit
@@ -53,10 +62,22 @@
 	dependents[index] = new InnerEmulationDependency(dependentScope, wasEnclosingInstanceSupplied);
 	//  System.out.println("Adding dependency: "+ new String(scope.enclosingType().readableName()) + " --> " + new String(this.readableName()));
 }
-/* Answer the receiver's constant pool name.
-*
-* NOTE: This method should only be used during/after code gen.
-*/
+public char[] computeUniqueKey(boolean withAccessFlags) {
+	ReferenceBinding enclosing = enclosingType();
+	ReferenceBinding temp;
+	while ((temp = enclosing.enclosingType()) != null)
+		enclosing = temp;
+	StringBuffer buffer = new StringBuffer();
+	buffer.append(enclosing.computeUniqueKey(withAccessFlags));
+	int semicolon = buffer.lastIndexOf(";"); //$NON-NLS-1$
+	buffer.insert(semicolon, '$');
+	semicolon = buffer.lastIndexOf(";"); //$NON-NLS-1$
+	buffer.insert(semicolon, this.sourceStart);
+	int length = buffer.length();
+	char[] uniqueKey = new char[length];
+	buffer.getChars(0, length, uniqueKey, 0);
+	return uniqueKey;
+}
 
 public char[] constantPoolName() /* java/lang/Object */ {
 	return constantPoolName;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
index 9084ae4..80173f6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -57,9 +57,9 @@
 	
 	/*
 	 * declaringUniqueKey # scopeIndex / varName
-	 * p.X { void foo() { int local; } } --> Lp/X;.foo()V#1/local
+	 * p.X { void foo() { int local; } } --> Lp/X;.foo()V#1/local^123
 	 */
-	public char[] computeUniqueKey() {
+	public char[] computeUniqueKey(boolean withAccessFlags) {
 		StringBuffer buffer = new StringBuffer();
 		
 		// declaring method or type
@@ -69,12 +69,12 @@
 		if (referenceContext instanceof AbstractMethodDeclaration) {
 			MethodBinding methodBinding = ((AbstractMethodDeclaration) referenceContext).binding;
 			if (methodBinding != null) {
-				buffer.append(methodBinding.computeUniqueKey());
+				buffer.append(methodBinding.computeUniqueKey(false/*without access flags*/));
 			}
 		} else if (referenceContext instanceof TypeDeclaration) {
 			TypeBinding typeBinding = ((TypeDeclaration) referenceContext).binding;
 			if (typeBinding != null) {
-				buffer.append(typeBinding.computeUniqueKey());
+				buffer.append(typeBinding.computeUniqueKey(false/*without access flags*/));
 			}
 		}
 
@@ -85,6 +85,12 @@
 		buffer.append('#');
 		buffer.append(this.name);
 		
+		// flags
+		if (withAccessFlags) {
+			buffer.append('^');
+			buffer.append(this.modifiers & AccJustFlag);
+		}
+		
 		int length = buffer.length();
 		char[] uniqueKey = new char[length];
 		buffer.getChars(0, length, uniqueKey, 0);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 686be8a..31bf1c8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -304,6 +304,29 @@
 			if (boxedType != null) return boxedType;
 			return new ProblemReferenceBinding(	JAVA_LANG_BOOLEAN, NotFound);				
 	}
+	// allow indirect unboxing conversion for wildcards and type parameters
+	switch (type.kind()) {
+		case Binding.WILDCARD_TYPE :
+		case Binding.TYPE_PARAMETER :
+			switch (type.erasure().id) {
+				case TypeIds.T_JavaLangBoolean :
+					return BooleanBinding;
+				case TypeIds.T_JavaLangByte :
+					return ByteBinding;
+				case TypeIds.T_JavaLangCharacter :
+					return CharBinding;
+				case TypeIds.T_JavaLangShort :
+					return ShortBinding;
+				case TypeIds.T_JavaLangDouble :
+					return DoubleBinding;
+				case TypeIds.T_JavaLangFloat :
+					return FloatBinding;
+				case TypeIds.T_JavaLangInteger :
+					return IntBinding;
+				case TypeIds.T_JavaLangLong :
+					return LongBinding;
+			}
+	}
 	return type;
 }	
 private PackageBinding computePackageFrom(char[][] constantPoolName) {
@@ -493,9 +516,11 @@
 	
 }
 
-public WildcardBinding createWildcard(ReferenceBinding genericType, int rank, TypeBinding bound, int kind) {
+public WildcardBinding createWildcard(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind) {
 	
 	// cached info is array of already created wildcard  types for this type
+	if (genericType == null) // pseudo wildcard denoting composite bounds for lub computation
+		genericType = ReferenceBinding.LUB_GENERIC;
 	WildcardBinding[] cachedInfo = (WildcardBinding[])this.uniqueWildcardBindings.get(genericType);
 	boolean needToGrow = false;
 	if (cachedInfo != null){
@@ -505,8 +530,16 @@
 			    WildcardBinding cachedType = cachedInfo[i];
 			    if (cachedType.genericType != genericType) continue nextCachedType; // remain of unresolved type
 			    if (cachedType.rank != rank) continue nextCachedType;
-			    if (cachedType.kind != kind) continue nextCachedType;
+			    if (cachedType.boundKind != boundKind) continue nextCachedType;
 			    if (cachedType.bound != bound) continue nextCachedType;
+			    if (cachedType.otherBounds != otherBounds) {
+			    	int cachedLength = cachedType.otherBounds == null ? 0 : cachedType.otherBounds.length;
+			    	int length = otherBounds == null ? 0 : otherBounds.length;
+			    	if (cachedLength != length) continue nextCachedType;
+			    	for (int j = 0; j < length; j++) {
+			    		if (cachedType.otherBounds[j] != otherBounds[j]) continue nextCachedType;
+			    	}
+			    }
 				// all match, reuse current
 				return cachedType;
 		}
@@ -522,7 +555,7 @@
 		this.uniqueWildcardBindings.put(genericType, cachedInfo);
 	}
 	// add new binding
-	WildcardBinding wildcard = new WildcardBinding(genericType, rank, bound, kind, this);
+	WildcardBinding wildcard = new WildcardBinding(genericType, rank, bound, otherBounds, boundKind, this);
 	cachedInfo[cachedInfo.length-1] = wildcard;
 	return wildcard;
 }
@@ -809,16 +842,16 @@
 			// ? super aType
 			wrapper.start++;
 			TypeBinding bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
-			return createWildcard(genericType, rank, bound, Wildcard.SUPER);
+			return createWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.SUPER);
 		case '+' :
 			// ? extends aType
 			wrapper.start++;
 			bound = getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
-			return createWildcard(genericType, rank, bound, Wildcard.EXTENDS);
+			return createWildcard(genericType, rank, bound, null /*no extra bound*/, Wildcard.EXTENDS);
 		case '*' :
 			// ?
 			wrapper.start++;
-			return createWildcard(genericType, rank, null, Wildcard.UNBOUND);
+			return createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 		default :
 			return getTypeFromTypeSignature(wrapper, staticVariables, enclosingType);
 	}
@@ -841,9 +874,9 @@
 
 public MethodVerifier methodVerifier() {
 	if (verifier == null)
-		verifier = this.options.sourceLevel < ClassFileConstants.JDK1_5
+		verifier = this.options.complianceLevel < ClassFileConstants.JDK1_5
 			? new MethodVerifier(this)
-			: new MethodVerifier15(this);
+			: new MethodVerifier15(this); // check for covariance even if sourceLevel is < 1.5
 	return verifier;
 }
 public void reset() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
index dc24ea2..96130ec 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
index 7f2443f..766a764 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -44,8 +44,6 @@
 		if (this.declaringClass.isStrictfp())
 			if (!(isNative() || isAbstract()))
 				this.modifiers |= AccStrictfp;
-		if (this.declaringClass.isViewedAsDeprecated() && !isDeprecated())
-			this.modifiers |= AccDeprecatedImplicitly;
 	}
 }
 public MethodBinding(int modifiers, TypeBinding[] parameters, ReferenceBinding[] thrownExceptions, ReferenceBinding declaringClass) {
@@ -60,6 +58,22 @@
 	this.thrownExceptions = initialMethodBinding.thrownExceptions;
 	this.declaringClass = declaringClass;
 }
+/* Answer true if the argument types & the receiver's parameters have the same erasure
+*/
+public final boolean areParameterErasuresEqual(MethodBinding method) {
+	TypeBinding[] args = method.parameters;
+	if (parameters == args)
+		return true;
+
+	int length = parameters.length;
+	if (length != args.length)
+		return false;
+
+	for (int i = 0; i < length; i++)
+		if (parameters[i] != args[i] && parameters[i].erasure() != args[i].erasure())
+			return false;
+	return true;
+}
 /* Answer true if the argument types & the receiver's parameters are equal
 */
 public final boolean areParametersEqual(MethodBinding method) {
@@ -103,22 +117,6 @@
 	return true;
 }
 
-/* Answer true if the argument types & the receiver's parameters have the same erasure
-*/
-public final boolean areParameterErasuresEqual(MethodBinding method) {
-	TypeBinding[] args = method.parameters;
-	if (parameters == args)
-		return true;
-
-	int length = parameters.length;
-	if (length != args.length)
-		return false;
-
-	for (int i = 0; i < length; i++)
-		if (parameters[i] != args[i] && parameters[i].erasure() != args[i].erasure())
-			return false;
-	return true;
-}
 /* API
 * Answer the receiver's binding type from Binding.BindingID.
 */
@@ -136,6 +134,22 @@
 	// isProtected() or isDefault()
 	return invocationPackage == declaringClass.getPackage();
 }
+/* Answer true if the type variables have the same erasure
+*/
+public final boolean areTypeVariableErasuresEqual(MethodBinding method) {
+	TypeVariableBinding[] vars = method.typeVariables;
+	if (this.typeVariables == vars)
+		return true;
+
+	int length = this.typeVariables.length;
+	if (length != vars.length)
+		return false;
+
+	for (int i = 0; i < length; i++)
+		if (this.typeVariables[i] != vars[i] && this.typeVariables[i].erasure() != vars[i].erasure())
+			return false;
+	return true;
+}
 /* Answer true if the receiver is visible to the type provided by the scope.
 * InvocationSite implements isSuperAccess() to provide additional information
 * if the receiver is protected.
@@ -201,9 +215,11 @@
 		if (invocationType.fPackage == declaringClass.fPackage) return true;
 		
 		ReferenceBinding currentType = invocationType;
+		TypeBinding receiverErasure = receiverType.erasure();		
+		ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure();
 		int depth = 0;
 		do {
-			if (declaringClass.isSuperclassOf(currentType)) {
+			if (currentType.findSuperTypeErasingTo(declaringErasure) != null) {
 				if (invocationSite.isSuperAccess()){
 					return true;
 				}
@@ -215,7 +231,7 @@
 					if (depth > 0) invocationSite.setDepth(depth);
 					return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
 				}
-				if (currentType == receiverType || currentType.isSuperclassOf((ReferenceBinding) receiverType)){
+				if (currentType == receiverErasure || ((ReferenceBinding)receiverErasure).findSuperTypeErasingTo(currentType) != null){
 					if (depth > 0) invocationSite.setDepth(depth);
 					return true;
 				}
@@ -274,14 +290,14 @@
 }
 /*
  * declaringUniqueKey dot selector genericSignature
- * p.X { <T> void bar(X<T> t) } --> Lp/X;.bar<T:Ljava/lang/Object;>(LX<TT;>;)V
+ * p.X { <T> void bar(X<T> t) } --> Lp/X;.bar<T:Ljava/lang/Object;>(LX<TT;>;)V^123
  */
-public char[] computeUniqueKey() {
-	return computeUniqueKey(this);
+public char[] computeUniqueKey(boolean withAccessFlags) {
+	return computeUniqueKey(this, withAccessFlags);
 }
-protected char[] computeUniqueKey(MethodBinding methodBinding) {
+protected char[] computeUniqueKey(MethodBinding methodBinding, boolean withAccessFlags) {
 	// declaring class 
-	char[] declaringKey = this.declaringClass.computeUniqueKey();
+	char[] declaringKey = this.declaringClass.computeUniqueKey(false/*without access flags*/);
 	int declaringLength = declaringKey.length;
 	
 	// selector
@@ -292,13 +308,36 @@
 	if (sig == null) sig = methodBinding.signature();
 	int signatureLength = sig.length;
 	
-	// compute unique key
-	char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength];
-	System.arraycopy(declaringKey, 0, uniqueKey, 0, declaringLength);
-	uniqueKey[declaringLength] = '.';
-	System.arraycopy(this.selector, 0, uniqueKey, declaringLength+1, selectorLength);
-	System.arraycopy(sig, 0, uniqueKey, declaringLength + 1 + selectorLength, signatureLength);
-	return uniqueKey;
+	if (withAccessFlags) {
+		// flags
+		String flags = Integer.toString(methodBinding.getAccessFlags());
+		int flagsLength = flags.length();
+		
+		char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength + 1 + flagsLength];
+		int index = 0;
+		System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+		index = declaringLength;
+		uniqueKey[index++] = '.';
+		System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
+		index += selectorLength;
+		System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
+		index += signatureLength;
+		uniqueKey[index++] = '^';
+		flags.getChars(0, flagsLength, uniqueKey, index);
+		// index += modifiersLength
+		return uniqueKey;
+	} else {
+		char[] uniqueKey = new char[declaringLength + 1 + selectorLength + signatureLength];
+		int index = 0;
+		System.arraycopy(declaringKey, 0, uniqueKey, index, declaringLength);
+		index = declaringLength;
+		uniqueKey[index++] = '.';
+		System.arraycopy(this.selector, 0, uniqueKey, index, selectorLength);
+		index += selectorLength;
+		System.arraycopy(sig, 0, uniqueKey, index, signatureLength);
+		//index += signatureLength;
+		return uniqueKey;
+	}
 }
 /* 
  * Answer the declaring class to use in the constant pool
@@ -351,6 +390,7 @@
 	}
 	if (needExceptionSignatures) {
 		for (int i = 0; i < length; i++) {
+			sig.append('^');
 			sig.append(this.thrownExceptions[i].genericTypeSignature());
 		}
 	}
@@ -373,7 +413,8 @@
 	if ((originalMethod.tagBits & TagBits.AnnotationResolved) == 0 && originalMethod.declaringClass instanceof SourceTypeBinding) {
 		TypeDeclaration typeDecl = ((SourceTypeBinding)originalMethod.declaringClass).scope.referenceContext;
 		AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(originalMethod);
-		ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod);
+		if (methodDecl != null)
+			ASTNode.resolveAnnotations(methodDecl.scope, methodDecl.annotations, originalMethod);
 	}
 	return originalMethod.tagBits;
 }
@@ -539,8 +580,7 @@
 /* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
 */
 public final boolean isViewedAsDeprecated() {
-	return (modifiers & AccDeprecated) != 0 ||
-		(modifiers & AccDeprecatedImplicitly) != 0;
+	return (modifiers & (AccDeprecated | AccDeprecatedImplicitly)) != 0;
 }
 
 /**
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index 67cf2dd..39d9264 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -49,6 +49,9 @@
 	public long[] definiteInits = new long[4];
 	public long[][] extraDefiniteInits = new long[4][];
 
+	// annotation support
+	public boolean insideTypeAnnotation = false;
+	
 	// inner-emulation
 	public SyntheticArgumentBinding[] extraSyntheticArguments;
 	
@@ -66,15 +69,16 @@
 	private void checkAndSetModifiersForConstructor(MethodBinding methodBinding) {
 		
 		int modifiers = methodBinding.modifiers;
+		final ReferenceBinding declaringClass = methodBinding.declaringClass;
 		if ((modifiers & AccAlternateModifierProblem) != 0)
-			problemReporter().duplicateModifierForMethod(
-				methodBinding.declaringClass,
-				(AbstractMethodDeclaration) referenceContext);
+			problemReporter().duplicateModifierForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext);
 
 		if (((ConstructorDeclaration) referenceContext).isDefaultConstructor) {
-			if (methodBinding.declaringClass.isPublic())
+			if (declaringClass.isEnum())
+				modifiers = AccPrivate;
+			else if (declaringClass.isPublic())
 				modifiers |= AccPublic;
-			else if (methodBinding.declaringClass.isProtected())
+			else if (declaringClass.isProtected())
 				modifiers |= AccProtected;
 		}
 
@@ -82,38 +86,44 @@
 		int realModifiers = modifiers & AccJustFlag;
 
 		// check for abnormal modifiers
-		int unexpectedModifiers =
-			~(AccPublic | AccPrivate | AccProtected | AccStrictfp);
-		if ((realModifiers & unexpectedModifiers) != 0)
+		int unexpectedModifiers = ~(AccPublic | AccPrivate | AccProtected | AccStrictfp);
+		if (declaringClass.isEnum() && !((ConstructorDeclaration) referenceContext).isDefaultConstructor) {
+			unexpectedModifiers = ~(AccPrivate | AccStrictfp);
+			if ((realModifiers & unexpectedModifiers) != 0) {
+				problemReporter().illegalModifierForEnumConstructor((AbstractMethodDeclaration) referenceContext);
+				modifiers &= ~AccJustFlag | ~unexpectedModifiers;
+			} else if ((((AbstractMethodDeclaration) referenceContext).modifiers & AccStrictfp) != 0) {
+				// must check the parse node explicitly
+				problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext);
+			}
+			modifiers |= AccPrivate; // enum constructor is implicitly private
+		} else if ((realModifiers & unexpectedModifiers) != 0) {
 			problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext);
-		else if (
-			(((AbstractMethodDeclaration) referenceContext).modifiers & AccStrictfp) != 0)
+			modifiers &= ~AccJustFlag | ~unexpectedModifiers;
+		} else if ((((AbstractMethodDeclaration) referenceContext).modifiers & AccStrictfp) != 0) {
 			// must check the parse node explicitly
 			problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext);
+		}
 
 		// check for incompatible modifiers in the visibility bits, isolate the visibility bits
 		int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate);
 		if ((accessorBits & (accessorBits - 1)) != 0) {
-			problemReporter().illegalVisibilityModifierCombinationForMethod(
-				methodBinding.declaringClass,
-				(AbstractMethodDeclaration) referenceContext);
+			problemReporter().illegalVisibilityModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext);
 
-			// need to keep the less restrictive
+			// need to keep the less restrictive so disable Protected/Private as necessary
 			if ((accessorBits & AccPublic) != 0) {
 				if ((accessorBits & AccProtected) != 0)
 					modifiers &= ~AccProtected;
 				if ((accessorBits & AccPrivate) != 0)
 					modifiers &= ~AccPrivate;
+			} else if ((accessorBits & AccProtected) != 0 && (accessorBits & AccPrivate) != 0) {
+				modifiers &= ~AccPrivate;
 			}
-			if ((accessorBits & AccProtected) != 0)
-				if ((accessorBits & AccPrivate) != 0)
-					modifiers &= ~AccPrivate;
 		}
 
 		// if the receiver's declaring class is a private nested type, then make sure the receiver is not private (causes problems for inner type emulation)
-		if (methodBinding.declaringClass.isPrivate())
-			if ((modifiers & AccPrivate) != 0)
-				modifiers &= ~AccPrivate;
+		if (declaringClass.isPrivate() && (modifiers & AccPrivate) != 0)
+			modifiers &= ~AccPrivate;
 
 		methodBinding.modifiers = modifiers;
 	}
@@ -123,72 +133,55 @@
 	private void checkAndSetModifiersForMethod(MethodBinding methodBinding) {
 		
 		int modifiers = methodBinding.modifiers;
+		final ReferenceBinding declaringClass = methodBinding.declaringClass;
 		if ((modifiers & AccAlternateModifierProblem) != 0)
-			problemReporter().duplicateModifierForMethod(
-				methodBinding.declaringClass,
-				(AbstractMethodDeclaration) referenceContext);
+			problemReporter().duplicateModifierForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext);
 
 		// after this point, tests on the 16 bits reserved.
 		int realModifiers = modifiers & AccJustFlag;
 
 		// set the requested modifiers for a method in an interface/annotation
-		if ((methodBinding.declaringClass.modifiers & AccInterface) != 0) {
+		if (declaringClass.isInterface()) {
 			if ((realModifiers & ~(AccPublic | AccAbstract)) != 0) {
-				if ((methodBinding.declaringClass.modifiers & AccAnnotation) != 0) {
+				if ((declaringClass.modifiers & AccAnnotation) != 0)
 					problemReporter().illegalModifierForAnnotationMember((AbstractMethodDeclaration) referenceContext);
-				} else {
+				else
 					problemReporter().illegalModifierForInterfaceMethod((AbstractMethodDeclaration) referenceContext);
-				}
 			}
 			return;
 		}
 
 		// check for abnormal modifiers
-		int unexpectedModifiers =
-			~(
-				AccPublic
-					| AccPrivate
-					| AccProtected
-					| AccAbstract
-					| AccStatic
-					| AccFinal
-					| AccSynchronized
-					| AccNative
-					| AccStrictfp);
-		if ((realModifiers & unexpectedModifiers) != 0)
+		int unexpectedModifiers = ~(AccPublic | AccPrivate | AccProtected
+			| AccAbstract | AccStatic | AccFinal | AccSynchronized | AccNative | AccStrictfp);
+		if ((realModifiers & unexpectedModifiers) != 0) {
 			problemReporter().illegalModifierForMethod((AbstractMethodDeclaration) referenceContext);
+			modifiers &= ~AccJustFlag | ~unexpectedModifiers;
+		}
 
 		// check for incompatible modifiers in the visibility bits, isolate the visibility bits
 		int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate);
 		if ((accessorBits & (accessorBits - 1)) != 0) {
-			problemReporter().illegalVisibilityModifierCombinationForMethod(
-				methodBinding.declaringClass,
-				(AbstractMethodDeclaration) referenceContext);
+			problemReporter().illegalVisibilityModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext);
 
-			// need to keep the less restrictive
+			// need to keep the less restrictive so disable Protected/Private as necessary
 			if ((accessorBits & AccPublic) != 0) {
 				if ((accessorBits & AccProtected) != 0)
 					modifiers &= ~AccProtected;
 				if ((accessorBits & AccPrivate) != 0)
 					modifiers &= ~AccPrivate;
+			} else if ((accessorBits & AccProtected) != 0 && (accessorBits & AccPrivate) != 0) {
+				modifiers &= ~AccPrivate;
 			}
-			if ((accessorBits & AccProtected) != 0)
-				if ((accessorBits & AccPrivate) != 0)
-					modifiers &= ~AccPrivate;
 		}
 
 		// check for modifiers incompatible with abstract modifier
 		if ((modifiers & AccAbstract) != 0) {
-			int incompatibleWithAbstract =
-				AccPrivate | AccStatic | AccFinal | AccSynchronized | AccNative | AccStrictfp;
+			int incompatibleWithAbstract = AccPrivate | AccStatic | AccFinal | AccSynchronized | AccNative | AccStrictfp;
 			if ((modifiers & incompatibleWithAbstract) != 0)
-				problemReporter().illegalAbstractModifierCombinationForMethod(
-					methodBinding.declaringClass,
-					(AbstractMethodDeclaration) referenceContext);
+				problemReporter().illegalAbstractModifierCombinationForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext);
 			if (!methodBinding.declaringClass.isAbstract())
-				problemReporter().abstractMethodInAbstractClass(
-					(SourceTypeBinding) methodBinding.declaringClass,
-					(AbstractMethodDeclaration) referenceContext);
+				problemReporter().abstractMethodInAbstractClass((SourceTypeBinding) declaringClass, (AbstractMethodDeclaration) referenceContext);
 		}
 
 		/* DISABLED for backward compatibility with javac (if enabled should also mark private methods as final)
@@ -198,17 +191,11 @@
 		*/
 		// native methods cannot also be tagged as strictfp
 		if ((modifiers & AccNative) != 0 && (modifiers & AccStrictfp) != 0)
-			problemReporter().nativeMethodsCannotBeStrictfp(
-				methodBinding.declaringClass,
-				(AbstractMethodDeclaration) referenceContext);
+			problemReporter().nativeMethodsCannotBeStrictfp(declaringClass, (AbstractMethodDeclaration) referenceContext);
 
 		// static members are only authorized in a static member or top level type
-		if (((realModifiers & AccStatic) != 0)
-			&& methodBinding.declaringClass.isNestedType()
-			&& !methodBinding.declaringClass.isStatic())
-			problemReporter().unexpectedStaticModifierForMethod(
-				methodBinding.declaringClass,
-				(AbstractMethodDeclaration) referenceContext);
+		if (((realModifiers & AccStatic) != 0) && declaringClass.isNestedType() && !declaringClass.isStatic())
+			problemReporter().unexpectedStaticModifierForMethod(declaringClass, (AbstractMethodDeclaration) referenceContext);
 
 		methodBinding.modifiers = modifiers;
 	}
@@ -303,7 +290,7 @@
 			method.binding = new MethodBinding(modifiers, null, null, declaringClass);
 			checkAndSetModifiersForConstructor(method.binding);
 		} else {
-			if ((declaringClass.modifiers & AccInterface) != 0) // interface or annotation type
+			if (declaringClass.isInterface()) // interface or annotation type
 				modifiers |= AccPublic | AccAbstract;
 			method.binding =
 				new MethodBinding(modifiers, method.selector, null, null, null, declaringClass);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
index e47cdd3..a51f5bc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 
 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 
@@ -66,15 +65,6 @@
 boolean areReturnTypesEqual(MethodBinding one, MethodBinding two) {
 	return areTypesEqual(one.returnType, two.returnType);
 }
-boolean canSkipInheritedMethods() {
-	if (this.type.superclass() != null && this.type.superclass().isAbstract())
-		return false;
-	return this.type.superInterfaces() == NoSuperInterfaces;
-}
-boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) {
-	return two == null // already know one is not null
-		|| one.declaringClass == two.declaringClass;
-}
 boolean areTypesEqual(TypeBinding one, TypeBinding two) {
 	if (one == two) return true;
 
@@ -88,6 +78,15 @@
 		return ((UnresolvedReferenceBinding) two).resolvedType == one;
 	return false; // all other type bindings are identical
 }
+boolean canSkipInheritedMethods() {
+	if (this.type.superclass() != null && this.type.superclass().isAbstract())
+		return false;
+	return this.type.superInterfaces() == NoSuperInterfaces;
+}
+boolean canSkipInheritedMethods(MethodBinding one, MethodBinding two) {
+	return two == null // already know one is not null
+		|| one.declaringClass == two.declaringClass;
+}
 void checkAbstractMethod(MethodBinding abstractMethod) {
 	if (mustImplementAbstractMethod(abstractMethod.declaringClass)) {
 		TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
@@ -99,14 +98,22 @@
 		}
 	}
 }
-void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length) {
+void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length, MethodBinding[] otherInheritedMethods) {
 	boolean isAnnotationMember = this.type.isAnnotationType();
 	nextMethod : for (int i = length; --i >= 0;) {
 		MethodBinding inheritedMethod = methods[i];
+		if (isAnnotationMember) { // annotation cannot override any method
+			problemReporter().annotationCannotOverrideMethod(currentMethod, inheritedMethod);
+			return; // do not repoort against subsequent inherited methods
+		}
 		if (currentMethod.isStatic() != inheritedMethod.isStatic()) {  // Cannot override a static method or hide an instance method
 			problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod);
 			continue nextMethod;
 		}
+		if (!areReturnTypesEqual(currentMethod, inheritedMethod)) {
+			problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod);
+			continue nextMethod;
+		}
 
 		if (inheritedMethod.isAbstract()) {
 			if (inheritedMethod.declaringClass.isInterface()) {
@@ -122,36 +129,39 @@
 			currentMethod.modifiers |= CompilerModifiers.AccOverriding;
 		}
 
-		if (isAnnotationMember) {
-			// annotation cannot override any method
-			problemReporter().annotationCannotOverrideMethod(currentMethod, inheritedMethod);
-			return; // do not repoort against subsequent inherited methods
-		}		
-		if (!areReturnTypesEqual(currentMethod, inheritedMethod)) {
-			problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod);
-		} else {
-			if (currentMethod.thrownExceptions != NoExceptions)
-				checkExceptions(currentMethod, inheritedMethod);
-			if (inheritedMethod.isFinal())
-				problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
-			if (!isAsVisible(currentMethod, inheritedMethod))
-				problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod);
-			if (environment.options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) {
-				if (!currentMethod.isViewedAsDeprecated() || environment.options.reportDeprecationInsideDeprecatedCode) {
-					// check against the other inherited methods to see if they hide this inheritedMethod
-					ReferenceBinding declaringClass = inheritedMethod.declaringClass;
-					if (declaringClass.isInterface())
-						for (int j = length; --j >= 0;)
-							if (i != j && methods[j].declaringClass.implementsInterface(declaringClass, false))
-								continue nextMethod;
+		if (currentMethod.thrownExceptions != NoExceptions)
+			checkExceptions(currentMethod, inheritedMethod);
+		if (inheritedMethod.isFinal())
+			problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
+		if (!isAsVisible(currentMethod, inheritedMethod))
+			problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod);
+		if (environment.options.reportDeprecationWhenOverridingDeprecatedMethod && inheritedMethod.isViewedAsDeprecated()) {
+			if (!currentMethod.isViewedAsDeprecated() || environment.options.reportDeprecationInsideDeprecatedCode) {
+				// check against the other inherited methods to see if they hide this inheritedMethod
+				ReferenceBinding declaringClass = inheritedMethod.declaringClass;
+				if (declaringClass.isInterface())
+					for (int j = length; --j >= 0;)
+						if (i != j && methods[j].declaringClass.implementsInterface(declaringClass, false))
+							continue nextMethod;
 
-					problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod);
-				}
+				problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod);
 			}
-			checkForBridgeMethod(currentMethod, inheritedMethod);
 		}
+		checkForBridgeMethod(currentMethod, inheritedMethod, otherInheritedMethods);
 	}
 }
+void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	// Remember that interfaces can only define public instance methods
+	if (concreteMethod.isStatic())
+		// Cannot inherit a static method which is specified as an instance method by an interface
+		problemReporter().staticInheritedMethodConflicts(type, concreteMethod, abstractMethods);	
+	if (!concreteMethod.isPublic())
+		// Cannot reduce visibility of a public method specified by an interface
+		problemReporter().inheritedMethodReducesVisibility(type, concreteMethod, abstractMethods);
+	if (concreteMethod.thrownExceptions != NoExceptions)
+		for (int i = abstractMethods.length; --i >= 0;)
+			checkExceptions(concreteMethod, abstractMethods[i]);
+}
 /*
 "8.4.4"
 Verify that newExceptions are all included in inheritedExceptions.
@@ -170,7 +180,13 @@
 				problemReporter(newMethod).incompatibleExceptionInThrowsClause(this.type, newMethod, inheritedMethod, newException);
 	}
 }
-void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] otherInheritedMethods) {
+	// no op before 1.5
+}
+void checkForInheritedNameClash(MethodBinding inheritedMethod, MethodBinding otherInheritedMethod) {
+	// no op before 1.5
+}
+void checkForNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) {
 	// no op before 1.5
 }
 void checkInheritedMethods(MethodBinding[] methods, int length) {
@@ -192,7 +208,7 @@
 		}
 	}
 	if (concreteMethod == null) {
-		if (this.type.isClass() && !this.type.isAbstract()) {
+		if (!this.type.isAbstract()) {
 			for (int i = length; --i >= 0;) {
 				if (mustImplementAbstractMethod(methods[i].declaringClass)) {
 					TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
@@ -214,17 +230,7 @@
 	for (int i = length; --i >= 0;)
 		if (methods[i] != concreteMethod)
 			abstractMethods[index++] = methods[i];
-
-	// Remember that interfaces can only define public instance methods
-	if (concreteMethod.isStatic())
-		// Cannot inherit a static method which is specified as an instance method by an interface
-		problemReporter().staticInheritedMethodConflicts(type, concreteMethod, abstractMethods);	
-	if (!concreteMethod.isPublic())
-		// Cannot reduce visibility of a public method specified by an interface
-		problemReporter().inheritedMethodReducesVisibility(type, concreteMethod, abstractMethods);
-	if (concreteMethod.thrownExceptions != NoExceptions)
-		for (int i = abstractMethods.length; --i >= 0;)
-			checkExceptions(concreteMethod, abstractMethods[i]);
+	checkConcreteInheritedMethod(concreteMethod, abstractMethods);
 }
 /*
 For each inherited method identifier (message pattern - vm signature minus the return type)
@@ -245,7 +251,7 @@
 					complain about missing implementation only if type is NOT an interface or abstract
 */
 void checkMethods() {
-	boolean mustImplementAbstractMethods = ((this.type.modifiers & IConstants.AccInterface) == 0) && !this.type.isAbstract();
+	boolean mustImplementAbstractMethods = mustImplementAbstractMethods();
 	boolean skipInheritedMethods = mustImplementAbstractMethods && canSkipInheritedMethods(); // have a single concrete superclass so only check overridden methods
 	char[][] methodSelectors = this.inheritedMethods.keyTable;
 	nextSelector : for (int s = methodSelectors.length; --s >= 0;) {
@@ -275,11 +281,13 @@
 						if (areMethodsEqual(currentMethod, inheritedMethod)) {
 							matchingInherited[++index] = inheritedMethod;
 							inherited[j] = null; // do not want to find it again
+						} else {
+							checkForNameClash(currentMethod, inheritedMethod);
 						}
 					}
 				}
 				if (index >= 0)
-					checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1); // pass in the length of matching
+					checkAgainstInheritedMethods(currentMethod, matchingInherited, index + 1, inherited); // pass in the length of matching
 			}
 		}
 
@@ -296,6 +304,8 @@
 					if (areMethodsEqual(inheritedMethod, otherInheritedMethod)) {
 						matchingInherited[++index] = otherInheritedMethod;
 						inherited[j] = null; // do not want to find it again
+					} else {
+						checkForInheritedNameClash(inheritedMethod, otherInheritedMethod);
 					}
 				}
 			}
@@ -332,6 +342,12 @@
 	// non visible abstract methods cannot be overridden so the type must be defined abstract
 	problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod);
 }
+void computeInheritedMethods() {
+	ReferenceBinding superclass = this.type.isInterface()
+		? this.type.scope.getJavaLangObject() // check interface methods against Object
+		: this.type.superclass(); // class or enum
+	computeInheritedMethods(superclass, type.superInterfaces());
+}
 /*
 Binding creation is responsible for reporting:
 	- all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations)
@@ -344,20 +360,18 @@
 	- check the type of any array is not void
 	- check that each exception type is Throwable or a subclass of it
 */
-void computeInheritedMethods() {
+void computeInheritedMethods(ReferenceBinding superclass, ReferenceBinding[] superInterfaces) {
 	// only want to remember inheritedMethods that can have an impact on the current type
 	// if an inheritedMethod has been 'replaced' by a supertype's method then skip it
 
 	this.inheritedMethods = new HashtableOfObject(51); // maps method selectors to an array of methods... must search to match paramaters & return type
 	ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[3][];
 	int lastPosition = -1;
-	ReferenceBinding[] itsInterfaces = type.superInterfaces();
+	ReferenceBinding[] itsInterfaces = superInterfaces;
 	if (itsInterfaces != NoSuperInterfaces)
 		interfacesToVisit[++lastPosition] = itsInterfaces;
 
-	ReferenceBinding superType = (this.type.modifiers & IConstants.AccInterface) == 0
-		? this.type.superclass() // class or enum
-		: this.type.scope.getJavaLangObject(); // check interface methods against Object
+	ReferenceBinding superType = superclass;
 	HashtableOfObject nonVisibleDefaultMethods = new HashtableOfObject(3); // maps method selectors to an array of methods
 	boolean allSuperclassesAreAbstract = true;
 
@@ -496,7 +510,12 @@
 	return inheritedMethod;
 }
 public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
-	return areReturnTypesEqual(method, inheritedMethod) && areParametersEqual(method, inheritedMethod);
+	return areReturnTypesEqual(method, inheritedMethod) && areMethodsEqual(method, inheritedMethod);
+}
+public boolean doReturnTypesCollide(MethodBinding method, MethodBinding inheritedMethod) {
+	return method.returnType != inheritedMethod.returnType
+		&& org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, inheritedMethod.selector)
+		&& method.areParametersEqual(inheritedMethod);
 }
 ReferenceBinding errorException() {
 	if (errorException == null)
@@ -542,6 +561,9 @@
 	}
 	return superclass.isAbstract();		// if it is a concrete class then we have already reported problem against it
 }
+boolean mustImplementAbstractMethods() {
+	return !this.type.isInterface() && !this.type.isAbstract();
+}
 ProblemReporter problemReporter() {
 	return this.type.scope.problemReporter();
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
index c12a487..bab6c81 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java
@@ -1,16 +1,21 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
-import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 
 class MethodVerifier15 extends MethodVerifier {
 
@@ -18,35 +23,45 @@
 	super(environment);
 }
 boolean areMethodsEqual(MethodBinding one, MethodBinding substituteTwo) {
-	TypeBinding[] oneParams = one.parameters;
-	TypeBinding[] twoParams = substituteTwo.parameters;
-	boolean checkParameters = false;
-	if (oneParams != twoParams) {
-		int length = oneParams.length;
-		if (length != twoParams.length) return false; // no match
+	return areParametersEqual(one, substituteTwo) && !doTypeVariablesClash(one, substituteTwo);
+}
+boolean areParametersEqual(MethodBinding one, MethodBinding two) {
+	TypeBinding[] oneArgs = one.parameters;
+	TypeBinding[] twoArgs = two.parameters;
+	if (oneArgs == twoArgs) return true;
 
-		for (int i = 0; i < length; i++) {
-			if (oneParams[i] != twoParams[i]) {
-				checkParameters |= oneParams[i].leafComponentType().isParameterizedType();
-				if (!areTypesEqual(oneParams[i], twoParams[i])) {
-					while (!checkParameters && ++i < length)
-						checkParameters |= oneParams[i].leafComponentType().isParameterizedType();
-					if (one.areParameterErasuresEqual(substituteTwo)) // at least one parameter may cause a name clash
-						detectNameClash(one, substituteTwo, checkParameters);
-					return false; // no match but needed to check for a name clash
-				}
-			}
+	int length = oneArgs.length;
+	if (length != twoArgs.length) return false;
+
+	for (int i = 0; i < length; i++) {
+		if (!areTypesEqual(oneArgs[i], twoArgs[i])) {
+			// methods with raw parameters are considered equal to inherited methods with parameterized parameters for backwards compatibility
+			if (oneArgs[i].isRawType() && !one.declaringClass.isInterface() && oneArgs[i].isEquivalentTo(twoArgs[i]))
+				continue;
+			return false;
 		}
 	}
-	return !detectNameClash(one, substituteTwo, checkParameters);
+	return true;
 }
 boolean areReturnTypesEqual(MethodBinding one, MethodBinding substituteTwo) {
 	if (one.returnType == substituteTwo.returnType) return true;
 
-	// methods from classes are always before methods from interfaces
-	if (one.declaringClass.isClass() || one.declaringClass.implementsInterface(substituteTwo.declaringClass, true))
+	// short is compatible with int, but as far as covariance is concerned, its not
+	if (one.returnType.isBaseType()) return false;
+
+	if (!one.declaringClass.isInterface()) {
+		if (one.declaringClass.id == TypeIds.T_JavaLangObject)
+			return substituteTwo.returnType.isCompatibleWith(one.returnType); // interface methods inherit from Object
+		return one.returnType.isCompatibleWith(substituteTwo.returnType);
+	}
+
+	// check for methods from Object, every interface inherits from Object
+	if (substituteTwo.declaringClass.id == TypeIds.T_JavaLangObject)
 		return one.returnType.isCompatibleWith(substituteTwo.returnType);
 
+	// both are interfaces, see if they're related
+	if (one.declaringClass.implementsInterface(substituteTwo.declaringClass, true))
+		return one.returnType.isCompatibleWith(substituteTwo.returnType);
 	if (substituteTwo.declaringClass.implementsInterface(one.declaringClass, true))
 		return substituteTwo.returnType.isCompatibleWith(one.returnType);
 
@@ -57,12 +72,9 @@
 boolean areTypesEqual(TypeBinding one, TypeBinding two) {
 	if (one == two) return true;
 
-	switch (one.kind()) {
-		case Binding.PARAMETERIZED_TYPE :
-		case Binding.RAW_TYPE :
-			return one.isEquivalentTo(two);
-//		case Binding.TYPE_PARAMETER : // won't work for variables from different classes - need substitution
-	}
+	// need to consider X<?> and X<? extends Object> as the same 'type'
+	if (one.isParameterizedType() && two.isParameterizedType())
+		return one.isEquivalentTo(two) && two.isEquivalentTo(one);
 
 	// Can skip this since we resolved each method before comparing it, see computeSubstituteMethod()
 	//	if (one instanceof UnresolvedReferenceBinding)
@@ -81,46 +93,165 @@
 	return two == null // already know one is not null
 		|| (one.declaringClass == two.declaringClass && !one.declaringClass.isParameterizedType());
 }
-void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod) {
-	MethodBinding originalInherited = inheritedMethod.original();
-	if (inheritedMethod != originalInherited) {
-		MethodBinding[] toCheck = (MethodBinding[]) this.currentMethods.get(currentMethod.selector);
-		if (toCheck.length > 1) {
-			// must check to see if a bridge method will collide with another current method (see 77861)
-			for (int i = 0, length = toCheck.length; i < length; i++) {
-				if (currentMethod != toCheck[i] && toCheck[i].areParameterErasuresEqual(originalInherited)) {
-					problemReporter(toCheck[i]).methodNameClash(toCheck[i], originalInherited); // bridge method will collide
-					return;
+void checkConcreteInheritedMethod(MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
+	super.checkConcreteInheritedMethod(concreteMethod, abstractMethods);
+
+	for (int i = 0, l = abstractMethods.length; i < l; i++) {
+		MethodBinding abstractMethod = abstractMethods[i];
+		if (concreteMethod.isVarargs() != abstractMethod.isVarargs())
+			problemReporter().varargsConflict(concreteMethod, abstractMethod, this.type);
+
+		// so the parameters are equal and the return type is compatible b/w the currentMethod & the substituted inheritedMethod
+		MethodBinding originalInherited = abstractMethod.original();
+		if (originalInherited.returnType != concreteMethod.returnType) {
+			if (abstractMethod.returnType.leafComponentType().isParameterizedType()) {
+				if (concreteMethod.returnType.leafComponentType().isRawType())
+					problemReporter().unsafeReturnTypeOverride(concreteMethod, originalInherited, this.type);
+			} else if (abstractMethod.hasSubstitutedReturnType() && originalInherited.returnType.leafComponentType().isTypeVariable()) {
+				if (((TypeVariableBinding) originalInherited.returnType.leafComponentType()).declaringElement == originalInherited) { // see 81618 - type variable from inherited method
+					TypeBinding currentReturnType = concreteMethod.returnType.leafComponentType();
+					if (!currentReturnType.isTypeVariable() || ((TypeVariableBinding) currentReturnType).declaringElement != concreteMethod)
+						problemReporter().unsafeReturnTypeOverride(concreteMethod, originalInherited, this.type);
 				}
 			}
 		}
+
+		this.type.addSyntheticBridgeMethod(originalInherited, concreteMethod.original());
+	}
+}
+void checkForBridgeMethod(MethodBinding currentMethod, MethodBinding inheritedMethod, MethodBinding[] otherInheritedMethods) {
+	if (currentMethod.isVarargs() != inheritedMethod.isVarargs())
+		problemReporter(currentMethod).varargsConflict(currentMethod, inheritedMethod, this.type);
+
+	// so the parameters are equal and the return type is compatible b/w the currentMethod & the substituted inheritedMethod
+	MethodBinding originalInherited = inheritedMethod.original();
+	if (originalInherited.returnType != currentMethod.returnType) {
+//		if (currentMethod.returnType.needsUncheckedConversion(inheritedMethod.returnType)) {
+//			problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type);
+		if (inheritedMethod.returnType.leafComponentType().isParameterizedType()) {
+			if (currentMethod.returnType.leafComponentType().isRawType())
+				problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type);
+		} else if (inheritedMethod.hasSubstitutedReturnType() && originalInherited.returnType.leafComponentType().isTypeVariable()) {
+			if (((TypeVariableBinding) originalInherited.returnType.leafComponentType()).declaringElement == originalInherited) { // see 81618 - type variable from inherited method
+				TypeBinding currentReturnType = currentMethod.returnType.leafComponentType();
+				if (!currentReturnType.isTypeVariable() || ((TypeVariableBinding) currentReturnType).declaringElement != currentMethod)
+					problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, this.type);
+			}
+		}
 	}
 
-	// so the parameters are equal and the return type is compatible b/w the currentMethod & the substituted inheritedMethod
-	if (originalInherited.returnType != currentMethod.returnType) {
-		TypeBinding originalReturnType = originalInherited.returnType.leafComponentType();
-		switch (originalReturnType.kind()) {
-			case Binding.GENERIC_TYPE :
-				// TODO (philippe) - we need this hack until SourceTypeBindings stop acting as ParameterizedTypes
-				if (originalReturnType != originalInherited.declaringClass || !inheritedMethod.returnType.leafComponentType().isParameterizedType())
-					break;
-			case Binding.PARAMETERIZED_TYPE :
-				if (!currentMethod.returnType.leafComponentType().isParameterizedType()) {
-					if (currentMethod.returnType.leafComponentType().isRawType() && inheritedMethod.returnType.leafComponentType().isRawType())
-						break;
-					problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, ((MethodDeclaration) currentMethod.sourceMethod()).returnType);
+	if (this.type.addSyntheticBridgeMethod(originalInherited, currentMethod.original()) != null) {
+		for (int i = 0, l = otherInheritedMethods.length; i < l; i++) {
+			if (otherInheritedMethods[i] != null) {
+				MethodBinding otherOriginal = otherInheritedMethods[i].original();
+				if (otherOriginal != otherInheritedMethods[i] && detectInheritedMethodClash(originalInherited, otherOriginal))
+					return;
+			}
+		}
+
+		// there is an ordering issue with the comparison in checkMethods
+		// its possible that compareTo(X) is walked first & removes Comparable.compareTo(T) from the inherited list before we can compare it to compareTo(Object)
+		// its only a problem when the matching inherited method creates a bridge method which collides with an unwalked current method
+		//		class X implements Comparable<X> {
+		//			public int compareTo(Object o) { return 0; }
+		//			public int compareTo(X o) { return 1; }
+		//		}
+		MethodBinding[] toCheck = (MethodBinding[]) this.currentMethods.get(currentMethod.selector);
+		for (int i = 0, l = toCheck.length; i < l; i++)
+			if (currentMethod != toCheck[i] && detectNameClash(toCheck[i], inheritedMethod))
+				return;
+	}
+}
+void checkForInheritedNameClash(MethodBinding inheritedMethod, MethodBinding otherInheritedMethod) {
+	// sent from checkMethods() to compare 2 inherited methods that are not 'equal'
+
+	// the 2 inherited methods clash because of a parameterized type overrides a raw type
+	//		interface I { void foo(A a); }
+	//		class Y { void foo(A<String> a) {} }
+	//		abstract class X extends Y implements I { }
+	//		class A<T> {}
+	// in this case the 2 inherited methods clash because of type variables
+	//		interface I { <T, S> void foo(T t); }
+	//		class Y { <T> void foo(T t) {} }
+	//		abstract class X extends Y implements I {}
+
+	if (!inheritedMethod.declaringClass.isInterface())
+		detectInheritedMethodClash(inheritedMethod, otherInheritedMethod);
+}
+
+void checkForNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) {
+	// sent from checkMethods() to compare a current method and an inherited method that are not 'equal'
+
+	// error cases:
+	//		abstract class AA<E extends Comparable> { abstract void test(E element); }
+	//		class A extends AA<Integer> { public void test(Integer i) {} }
+	//		public class B extends A { public void test(Comparable i) {} }
+	// AND
+	//		interface I<E extends Comparable> { void test(E element); }
+	//		class A implements I<Integer> { public void test(Integer i) {} }
+	//		public class B extends A { public void test(Comparable i) {} }
+	// AND
+	//		abstract class Y implements EqualityComparable<Integer>, Equivalent<String> {
+	//			public boolean equalTo(Integer other) { return true; }
+	//		}
+	//		interface Equivalent<T> { boolean equalTo(T other); }
+	//		interface EqualityComparable<T> { boolean equalTo(T other); }
+	// AND
+	//		class Y implements EqualityComparable, Equivalent<String>{
+	//			public boolean equalTo(String other) { return true; }
+	//			public boolean equalTo(Object other) { return true; }
+	//		}
+	//		interface Equivalent<T> { boolean equalTo(T other); }
+	//		interface EqualityComparable { boolean equalTo(Object other); }
+
+	if (currentMethod.declaringClass.isInterface()) return;
+
+	if (!detectNameClash(currentMethod, inheritedMethod)) { // check up the hierarchy for skipped inherited methods
+		TypeBinding[] currentParams = currentMethod.parameters;
+		TypeBinding[] inheritedParams = inheritedMethod.parameters;
+		int length = currentParams.length;
+		if (length != inheritedParams.length) return; // no match
+
+		for (int i = 0; i < length; i++)
+			if (currentParams[i] != inheritedParams[i])
+				if (currentParams[i].isBaseType() != inheritedParams[i].isBaseType() || !inheritedParams[i].isCompatibleWith(currentParams[i]))
+					return; // no chance that another inherited method's bridge method can collide
+
+		ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[3][];
+		int lastPosition = -1;
+		ReferenceBinding[] itsInterfaces = null;
+		ReferenceBinding superType = this.type.superclass;
+		while (superType != null && superType.isValidBinding()) {
+			MethodBinding[] methods = superType.getMethods(currentMethod.selector);
+			for (int m = 0, n = methods.length; m < n; m++)
+				if (!areMethodsEqual(currentMethod, methods[m]) && detectNameClash(currentMethod, methods[m]))
+					return;
+			if ((itsInterfaces = superType.superInterfaces()) != NoSuperInterfaces) {
+				if (++lastPosition == interfacesToVisit.length)
+					System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
+				interfacesToVisit[lastPosition] = itsInterfaces;
+			}
+			superType = superType.superclass();
+		}
+
+		for (int i = 0; i <= lastPosition; i++) {
+			ReferenceBinding[] interfaces = interfacesToVisit[i];
+			for (int j = 0, l = interfaces.length; j < l; j++) {
+				superType = interfaces[j];
+				if (superType.isValidBinding()) {
+					MethodBinding[] methods = superType.getMethods(currentMethod.selector);
+					for (int m = 0, n = methods.length; m < n; m++)
+						if (!areMethodsEqual(currentMethod, methods[m]) && detectNameClash(currentMethod, methods[m]))
+							return;
+					if ((itsInterfaces = superType.superInterfaces()) != NoSuperInterfaces) {
+						if (++lastPosition == interfacesToVisit.length)
+							System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
+						interfacesToVisit[lastPosition] = itsInterfaces;
+					}
 				}
-				break;
-			case Binding.TYPE_PARAMETER : // see 81618
-				if (((TypeVariableBinding) originalReturnType).declaringElement == originalInherited) {
-					TypeBinding returnType = currentMethod.returnType.leafComponentType();
-					if (!returnType.isTypeVariable() || ((TypeVariableBinding) returnType).declaringElement != currentMethod)
-						problemReporter(currentMethod).unsafeReturnTypeOverride(currentMethod, originalInherited, ((MethodDeclaration) currentMethod.sourceMethod()).returnType);
-				}
-				break;
+			}
 		}
 	}
-	this.type.addSyntheticBridgeMethod(originalInherited, currentMethod);
 }
 void checkInheritedMethods(MethodBinding[] methods, int length) {
 	int count = length;
@@ -148,11 +279,40 @@
 
 	super.checkInheritedMethods(methods, length);
 }
+void checkTypeVariableMethods() {
+	char[][] methodSelectors = this.inheritedMethods.keyTable;
+	nextSelector : for (int s = methodSelectors.length; --s >= 0;) {
+		if (methodSelectors[s] == null) continue nextSelector;
+		MethodBinding[] inherited = (MethodBinding[]) this.inheritedMethods.valueTable[s];
+		if (inherited.length == 1) continue nextSelector;
+
+		int index = -1;
+		MethodBinding[] matchingInherited = new MethodBinding[inherited.length];
+		for (int i = 0, length = inherited.length; i < length; i++) {
+			while (index >= 0) matchingInherited[index--] = null; // clear the previous contents of the matching methods
+			MethodBinding inheritedMethod = inherited[i];
+			if (inheritedMethod != null) {
+				matchingInherited[++index] = inheritedMethod;
+				for (int j = i + 1; j < length; j++) {
+					MethodBinding otherInheritedMethod = inherited[j];
+					if (canSkipInheritedMethods(inheritedMethod, otherInheritedMethod))
+						continue;
+					otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
+					if (areMethodsEqual(inheritedMethod, otherInheritedMethod)) {
+						matchingInherited[++index] = otherInheritedMethod;
+						inherited[j] = null; // do not want to find it again
+					}
+				}
+			}
+			if (index > 0)
+				checkInheritedMethods(matchingInherited, index + 1); // pass in the length of matching
+		}
+	}
+}
 MethodBinding computeSubstituteMethod(MethodBinding inheritedMethod, MethodBinding currentMethod) {
 	if (inheritedMethod == null) return null;
 
 	// due to hierarchy & compatibility checks, we need to ensure these 2 methods are resolved
-	// should we push these tests to where they're needed? returnType.isCompatibleWith && parameter isEquivalentTo ?
 	if (currentMethod.declaringClass instanceof BinaryTypeBinding)
 		((BinaryTypeBinding) currentMethod.declaringClass).resolveTypesFor(currentMethod);
 	if (inheritedMethod.declaringClass instanceof BinaryTypeBinding)
@@ -175,22 +335,29 @@
 	ParameterizedGenericMethodBinding substitute =
 		new ParameterizedGenericMethodBinding(inheritedMethod, arguments, this.environment);
 	for (int i = 0; i < inheritedLength; i++)
-	    if (!inheritedTypeVariables[i].boundCheck(substitute, arguments[i]))
+	    if (inheritedTypeVariables[i].boundCheck(substitute, arguments[i]) != TypeConstants.OK)
 	    	return inheritedMethod; // incompatible due to bound check
    return substitute;
 }
-boolean detectNameClash(MethodBinding one, MethodBinding substituteTwo, boolean checkParameters) {
-	if (doTypeVariablesClash(one, substituteTwo) || (checkParameters && doParametersClash(one, substituteTwo))) {
-		if (this.type == one.declaringClass)
-		 	problemReporter(one).methodNameClash(one, substituteTwo);
-		else
-			problemReporter().inheritedMethodsHaveNameClash(this.type, one, substituteTwo);
+boolean detectInheritedMethodClash(MethodBinding inherited, MethodBinding otherInherited) {
+	if (!inherited.areParameterErasuresEqual(otherInherited) || inherited.returnType.erasure() != otherInherited.returnType.erasure()) return false;
+	if (doTypeVariablesClash(inherited, otherInherited) || doParametersClash(inherited, otherInherited)) {
+		problemReporter().inheritedMethodsHaveNameClash(this.type, inherited, otherInherited);
 		return true;
 	}
 	return false;
 }
-public boolean doesMethodOverride(MethodBinding method, MethodBinding inheritedMethod) {
-	return super.doesMethodOverride(method, computeSubstituteMethod(inheritedMethod, method));
+boolean detectNameClash(MethodBinding current, MethodBinding inherited) {
+	MethodBinding original = inherited.original(); // can be the same as inherited
+	if (!current.areParameterErasuresEqual(original) || current.returnType.erasure() != original.returnType.erasure()) return false;
+	if (doTypeVariablesClash(current, inherited) || doParametersClash(current, original)) {
+		problemReporter(current).methodNameClash(current, original);
+		return true;
+	}
+	return false;
+}
+public boolean doesMethodOverride(MethodBinding one, MethodBinding two) {
+	return super.doesMethodOverride(one, computeSubstituteMethod(two, one));
 }
 boolean doParametersClash(MethodBinding one, MethodBinding substituteTwo) {
 	// must check each parameter pair to see if parameterized types are compatible
@@ -198,24 +365,86 @@
 	TypeBinding[] twoParams = substituteTwo.parameters;
 	for (int i = 0, l = oneParams.length; i < l; i++) {
 		if (oneParams[i] == twoParams[i]) continue;
-		if (!oneParams[i].leafComponentType().isParameterizedType()) continue;
-
-		if (!twoParams[i].leafComponentType().isParameterizedType()
-			|| !oneParams[i].isEquivalentTo(twoParams[i])
-			|| !twoParams[i].isEquivalentTo(oneParams[i])) {
-				return true;
+		switch (oneParams[i].leafComponentType().kind()) {
+			case Binding.PARAMETERIZED_TYPE :
+				if (!twoParams[i].leafComponentType().isParameterizedType()
+					|| !oneParams[i].isEquivalentTo(twoParams[i])
+					|| !twoParams[i].isEquivalentTo(oneParams[i])) {
+						return true;
+				}
+				break;
+			case Binding.TYPE_PARAMETER :
+				return true; // type variables must be identical (due to substitution) given their erasures are equal
 		}
+		if (twoParams[i].leafComponentType().isTypeVariable())
+			return true; // type variables must be identical (due to substitution) given their erasures are equal
 	}
 	return false;
 }
+public boolean doReturnTypesCollide(MethodBinding method, MethodBinding inheritedMethod) {
+	MethodBinding sub = computeSubstituteMethod(inheritedMethod, method);
+	return org.eclipse.jdt.core.compiler.CharOperation.equals(method.selector, sub.selector)
+		&& method.areParameterErasuresEqual(sub)
+		&& !areReturnTypesEqual(method, sub);
+}
 boolean doTypeVariablesClash(MethodBinding one, MethodBinding substituteTwo) {
-	TypeBinding[] currentVars = one.typeVariables;
-	TypeBinding[] inheritedVars = substituteTwo.original().typeVariables;
-	return currentVars.length != inheritedVars.length && currentVars.length > 0;
+	return one.typeVariables != NoTypeVariables && !one.areTypeVariableErasuresEqual(substituteTwo.original());
 }
 boolean isInterfaceMethodImplemented(MethodBinding inheritedMethod, MethodBinding existingMethod, ReferenceBinding superType) {
 	inheritedMethod = computeSubstituteMethod(inheritedMethod, existingMethod);
 	return inheritedMethod.returnType == existingMethod.returnType
 		&& super.isInterfaceMethodImplemented(inheritedMethod, existingMethod, superType);
 }
-}
\ No newline at end of file
+boolean mustImplementAbstractMethod(ReferenceBinding declaringClass) {
+	if (!this.type.isEnum())
+		return super.mustImplementAbstractMethod(declaringClass);
+	if (this.type.isAnonymousType())
+		return true; // body of enum constant must implement any inherited abstract methods
+	if (this.type.isAbstract())
+		return false; // is an enum that has since been tagged as abstract by the code below
+
+	// enum type needs to implement abstract methods if one of its constants does not supply a body
+	TypeDeclaration typeDeclaration = this.type.scope.referenceContext;
+	FieldDeclaration[] fields = typeDeclaration.fields;
+	int length = typeDeclaration.fields == null ? 0 : typeDeclaration.fields.length;
+	if (length == 0) return true; // has no constants so must implement the method itself
+	for (int i = 0; i < length; i++) {
+		FieldDeclaration fieldDecl = fields[i];
+		if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT)
+			if (!(fieldDecl.initialization instanceof QualifiedAllocationExpression))
+				return true;
+	}
+
+	// tag this enum as abstract since an abstract method must be implemented AND all enum constants define an anonymous body
+	// as a result, each of its anonymous constants will see it as abstract and must implement each inherited abstract method
+	this.type.modifiers |= IConstants.AccAbstract;
+	return false;
+}
+void verify(SourceTypeBinding someType) {
+	if (someType.isAnnotationType())
+		someType.detectAnnotationCycle();
+
+	super.verify(someType);
+
+	for (int i = someType.typeVariables.length; --i >= 0;) {
+		TypeVariableBinding var = someType.typeVariables[i];
+		// must verify bounds if the variable has more than 1
+		if (var.superInterfaces == NoSuperInterfaces) continue;
+		if (var.superInterfaces.length == 1 && var.superclass.id == TypeIds.T_JavaLangObject) continue;
+
+		this.currentMethods = new HashtableOfObject(0);
+		ReferenceBinding superclass = var.superclass();
+		if (superclass.kind() == Binding.TYPE_PARAMETER)
+			superclass = (ReferenceBinding) superclass.erasure();
+		ReferenceBinding[] itsInterfaces = var.superInterfaces();
+		ReferenceBinding[] superInterfaces = new ReferenceBinding[itsInterfaces.length];
+		for (int j = itsInterfaces.length; --j >= 0;) {
+			superInterfaces[j] = itsInterfaces[j].kind() == Binding.TYPE_PARAMETER
+				? (ReferenceBinding) itsInterfaces[j].erasure()
+				: itsInterfaces[j];
+		}
+		computeInheritedMethods(superclass, superInterfaces);
+		checkTypeVariableMethods();
+	}
+}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
index 2b78a5d..1e220cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
index 9f29f95..d62d0cc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,6 +15,8 @@
 import org.eclipse.jdt.internal.compiler.util.HashtableOfType;
 
 public class PackageBinding extends Binding implements TypeConstants {
+	public long tagBits = 0; // See values in the interface TagBits below
+	
 	public char[][] compoundName;
 	PackageBinding parent;
 	public LookupEnvironment environment;
@@ -66,7 +68,7 @@
  * slash separated name
  * org.eclipse.jdt.core --> org/eclipse/jdt/core
  */
-public char[] computeUniqueKey() {
+public char[] computeUniqueKey(boolean withAccessFlags) {
 	return CharOperation.concatWith(compoundName, '/');
 }
 private PackageBinding findPackage(char[] name) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
index d494449..ab78214 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,11 +25,12 @@
 	public ParameterizedFieldBinding(ParameterizedTypeBinding parameterizedDeclaringClass, FieldBinding originalField) {
 	    super (
 	            originalField.name, 
-	            originalField.isStatic() ? originalField.type : parameterizedDeclaringClass.substitute(originalField.type), 
+	            originalField.isStatic() ? originalField.type : Scope.substitute(parameterizedDeclaringClass, originalField.type), 
 	            originalField.modifiers, 
 	            parameterizedDeclaringClass, 
 	            null);
 	    this.originalField = originalField;
+	    this.id = originalField.id;
 	}
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.VariableBinding#constant()
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
index bf283be..659cde6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,7 +13,6 @@
 import java.util.HashMap;
 import java.util.Map;
 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 
 /**
  * Binding denoting a generic method after type parameter substitutions got performed.
@@ -29,24 +28,230 @@
     public boolean wasInferred; // only set to true for instances resulting from method invocation inferrence
     public boolean isRaw; // set to true for method behaving as raw for substitution purpose
     public MethodBinding tiebreakMethod;
-    
-    /**
-     * Create method of parameterized type, substituting original parameters with type arguments.
-     */
-	public ParameterizedGenericMethodBinding(MethodBinding originalMethod, TypeBinding[] typeArguments, LookupEnvironment environment) {
+	public boolean isUnchecked; // indicates whether inferred arguments used unchecked conversion during bound check or was raw
+	
+	/**
+	 * Perform inference of generic method type parameters and/or expected type
+	 */	
+	public static MethodBinding computeCompatibleMethod(MethodBinding originalMethod, TypeBinding[] arguments, Scope scope, InvocationSite invocationSite) {
+		
+		ParameterizedGenericMethodBinding methodSubstitute;
+		TypeVariableBinding[] typeVariables = originalMethod.typeVariables;
+		TypeBinding[] substitutes = invocationSite.genericTypeArguments();
+		
+		computeSubstitutes: {
+			if (substitutes != null) {
+				// explicit type arguments got supplied
+				if (substitutes.length != typeVariables.length) {
+			        // incompatible due to wrong arity
+			        return new ProblemMethodBinding(originalMethod, originalMethod.selector, substitutes, TypeParameterArityMismatch);
+				}
+				methodSubstitute = new ParameterizedGenericMethodBinding(originalMethod, substitutes, scope.environment());
+				break computeSubstitutes;
+			}
+			
+			// perform type argument inference (15.12.2.7)
+				
+			// initializes the map of substitutes (var --> type[][]{ equal, extends, super}
+			TypeBinding[] parameters = originalMethod.parameters;
+			int varLength = typeVariables.length;
+			Map collectedSubstitutes = new HashMap(varLength);
+			for (int i = 0; i < varLength; i++)
+				collectedSubstitutes.put(typeVariables[i], new TypeBinding[3][]);
+			
+			substitutes = new TypeBinding[varLength];
+			methodSubstitute = inferFromArgumentTypes(scope, originalMethod, arguments, parameters, collectedSubstitutes, substitutes);
+			if (methodSubstitute == null) 
+				return null;
+			// substitutes may hold null to denote unresolved vars, but null arguments got replaced with respective original variable in param method
+			
+			// 15.12.2.8 - inferring unresolved type arguments
+			if (hasUnresolvedTypeArgument(substitutes)) {
+				TypeBinding expectedType = null;
+				// if message invocation has expected type
+				if (invocationSite instanceof MessageSend) {
+					MessageSend message = (MessageSend) invocationSite;
+					expectedType = message.expectedType;
+				}
+				TypeBinding upperBound = null;
+				if (methodSubstitute.returnType.isTypeVariable()) {
+					// should be: if no expected type, then assume Object
+					// actually it rather seems to handle the returned variable case by expecting its erasure instead
+					upperBound = methodSubstitute.returnType.erasure();
+				} else {
+					if (methodSubstitute.returnType.id != TypeIds.T_void)
+						upperBound = scope.getJavaLangObject(); 
+				}
+				// Object o = foo(); // where <T extends Serializable> T foo();
+				if (expectedType == null || upperBound.isCompatibleWith(expectedType)) {
+					expectedType = upperBound;
+				}
+				methodSubstitute = methodSubstitute.inferFromExpectedType(scope, expectedType, collectedSubstitutes, substitutes);
+				if (methodSubstitute == null) 
+					return null;
+			}
+		}
 
-	    this.environment = environment;
-		this.modifiers = originalMethod.modifiers;
-		this.selector = originalMethod.selector;
-		this.declaringClass = originalMethod.declaringClass;
-	    this.typeVariables = NoTypeVariables;
-	    this.typeArguments = typeArguments;
-	    this.isRaw = false;
-	    this.originalMethod = originalMethod;
-	    this.parameters = Scope.substitute(this, originalMethod.parameters);
-	    this.thrownExceptions = Scope.substitute(this, originalMethod.thrownExceptions);
-	    this.returnType = this.substitute(originalMethod.returnType);
-	    this.wasInferred = true;// resulting from method invocation inferrence
+		// bounds check
+		if (!methodSubstitute.isRaw) {
+			for (int i = 0, length = typeVariables.length; i < length; i++) {
+			    TypeVariableBinding typeVariable = typeVariables[i];
+			    TypeBinding substitute = methodSubstitute.typeArguments[i];
+				switch (typeVariable.boundCheck(methodSubstitute, substitute)) {
+					case TypeConstants.MISMATCH :
+				        // incompatible due to bound check
+				        return new ProblemMethodBinding(methodSubstitute, originalMethod.selector, new TypeBinding[]{substitute, typeVariables[i] }, ParameterBoundMismatch);
+					case TypeConstants.UNCHECKED :
+						// tolerate unchecked bounds
+						methodSubstitute.isUnchecked = true;
+						break;
+				}
+			}
+		}
+
+		return methodSubstitute;
+	}
+
+	/**
+	 * Returns true if any unresolved variable is detected, i.e. any variable is substituted with itself
+	 */
+	private static boolean hasUnresolvedTypeArgument(TypeBinding[] substitutes) {
+		for (int i = 0, varLength = substitutes.length; i <varLength; i++) {
+			if (substitutes[i] == null) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Collect argument type mapping, handling varargs
+	 */
+	private static ParameterizedGenericMethodBinding inferFromArgumentTypes(Scope scope, MethodBinding originalMethod, TypeBinding[] arguments, TypeBinding[] parameters, Map collectedSubstitutes, TypeBinding[] substitutes) {
+
+		if (originalMethod.isVarargs()) {
+			int paramLength = parameters.length;
+			int minArgLength = paramLength - 1;
+			int argLength = arguments.length;
+			// process mandatory arguments
+			for (int i = 0; i < minArgLength; i++) {
+				parameters[i].collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
+			}
+			// process optional arguments
+			if (minArgLength < argLength) {
+				TypeBinding varargType = parameters[minArgLength]; // last arg type - as is ?
+				TypeBinding lastArgument = arguments[minArgLength];
+				if (paramLength != argLength // argument is passed as is ?
+						||  (lastArgument != NullBinding
+								&& (lastArgument.dimensions() == 0 || lastArgument.leafComponentType().isBaseType() != varargType.leafComponentType().isBaseType()))) { 
+					varargType = ((ArrayBinding)varargType).elementsType(); // eliminate one array dimension
+				}
+				for (int i = minArgLength; i < argLength; i++) {
+					varargType.collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
+				}
+			}
+		} else {
+			int paramLength = parameters.length;
+			for (int i = 0; i < paramLength; i++) {
+				parameters[i].collectSubstitutes(scope, arguments[i], collectedSubstitutes, CONSTRAINT_EXTENDS);
+			}
+		}
+		TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
+		int varLength = originalVariables.length;
+		substitutes = resolveSubstituteConstraints(scope, originalVariables , substitutes, false/*ignore Ti<:Uk*/, collectedSubstitutes);
+		if (substitutes == null) 
+			return null; // incompatible
+		if (substitutes.length == 0) {
+			// raw generic method inferred
+			return new ParameterizedGenericMethodBinding(originalMethod, (RawTypeBinding)null, scope.environment());
+		}
+		// apply inferred variable substitutions - replacing unresolved variable with original ones in param method
+		TypeBinding[] resolvedSubstitutes = substitutes;
+		for (int i = 0; i < varLength; i++) {
+			if (substitutes[i] == null) {
+				if (resolvedSubstitutes == substitutes) {
+					System.arraycopy(substitutes, 0, resolvedSubstitutes = new TypeBinding[varLength], 0, i); // clone to replace null with original variable in param method
+				}
+				resolvedSubstitutes[i] = originalVariables[i];
+			} else if (resolvedSubstitutes != substitutes) {
+				resolvedSubstitutes[i] = substitutes[i];
+			}
+		}
+		return new ParameterizedGenericMethodBinding(originalMethod, resolvedSubstitutes, scope.environment());		
+	}
+	
+	private static TypeBinding[] resolveSubstituteConstraints(Scope scope, TypeVariableBinding[] typeVariables, TypeBinding[] substitutes, boolean considerEXTENDSConstraints, Map collectedSubstitutes) {
+		if (collectedSubstitutes.isEmpty()) {
+			// raw generic method inferred
+			return NoTypes; // empty array
+		}
+		int varLength = typeVariables.length;
+		
+		// check Tj=U constraints
+		nextTypeParameter: 
+			for (int i = 0; i < varLength; i++) {
+				TypeVariableBinding current = typeVariables[i];
+				TypeBinding substitute = substitutes[i];
+				if (substitute != null) continue nextTypeParameter; // already inferred previously
+				TypeBinding[][] variableSubstitutes = (TypeBinding[][]) collectedSubstitutes.get(current);
+				TypeBinding [] equalSubstitutes = variableSubstitutes[CONSTRAINT_EQUAL];
+				if (equalSubstitutes != null) {
+					nextConstraint:
+						for (int j = 0, equalLength = equalSubstitutes.length; j < equalLength; j++) {
+							TypeBinding equalSubstitute = equalSubstitutes[j];
+							if (equalSubstitute == null) continue nextConstraint;
+//							if (equalSubstitute == current) continue nextConstraint;
+//							if (equalSubstitute.isTypeVariable()) {
+//								TypeVariableBinding variable = (TypeVariableBinding) equalSubstitute;
+//								// substituted by a variable of the same method, ignore
+//								if (variable.rank < varLength && typeVariables[variable.rank] == variable) {
+//									// TODO (philippe) rewrite all other constraints to use current instead.
+//									continue nextConstraint;
+//								}
+//							}
+							substitutes[i] = equalSubstitute;
+							continue nextTypeParameter; // pick first match, applicability check will rule out invalid scenario where others were present
+						}
+				}
+			}
+		if (hasUnresolvedTypeArgument(substitutes)) {
+			// check Tj>:U constraints
+			nextTypeParameter: 
+				for (int i = 0; i < varLength; i++) {
+					TypeVariableBinding current = typeVariables[i];
+					TypeBinding substitute = substitutes[i];
+					if (substitute != null) continue nextTypeParameter; // already inferred previously
+					TypeBinding[][] variableSubstitutes = (TypeBinding[][]) collectedSubstitutes.get(current);
+					TypeBinding [] bounds = variableSubstitutes[CONSTRAINT_SUPER];
+					if (bounds == null) continue nextTypeParameter;
+					TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(bounds);
+					if (mostSpecificSubstitute == null)
+						return null; // incompatible
+					if (mostSpecificSubstitute != VoidBinding) {
+						substitutes[i] = mostSpecificSubstitute;
+					}
+				}
+		}
+		if (considerEXTENDSConstraints && hasUnresolvedTypeArgument(substitutes)) {
+			// check Tj<:U constraints
+			nextTypeParameter: 
+				for (int i = 0; i < varLength; i++) {
+					TypeVariableBinding current = typeVariables[i];
+					TypeBinding substitute = substitutes[i];
+					if (substitute != null) continue nextTypeParameter; // already inferred previously
+					TypeBinding[][] variableSubstitutes = (TypeBinding[][]) collectedSubstitutes.get(current);
+					TypeBinding [] bounds = variableSubstitutes[CONSTRAINT_EXTENDS];
+					if (bounds == null) continue nextTypeParameter;
+					TypeBinding[] glb = Scope.greaterLowerBound(bounds);
+					TypeBinding mostSpecificSubstitute = null;
+					if (glb != null) mostSpecificSubstitute = glb[0]; // TODO (philippe) need to improve
+						//TypeBinding mostSpecificSubstitute = scope.greaterLowerBound(bounds);
+						if (mostSpecificSubstitute != null) {
+							substitutes[i] = mostSpecificSubstitute;
+						}
+					} 
+		}
+		return substitutes;
 	}
 	
 	/**
@@ -62,6 +267,7 @@
 			rawArguments[i] = originalVariables[i].erasure();
 		}		
 	    this.isRaw = true;
+		this.isUnchecked = false;
 	    this.environment = environment;
 		this.modifiers = originalMethod.modifiers;
 		this.selector = originalMethod.selector;
@@ -76,126 +282,47 @@
 	    this.thrownExceptions = Scope.substitute(this, 	ignoreRawTypeSubstitution 
 	    									? originalMethod.thrownExceptions // no substitution if original was static
 	    									: Scope.substitute(rawType, originalMethod.thrownExceptions));
-	    this.returnType = this.substitute(ignoreRawTypeSubstitution 
+	    this.returnType = Scope.substitute(this, ignoreRawTypeSubstitution 
 	    									? originalMethod.returnType // no substitution if original was static
-	    									: rawType.substitute(originalMethod.returnType));
+	    									: Scope.substitute(rawType, originalMethod.returnType));
 	    this.wasInferred = false; // not resulting from method invocation inferrence
 	}
-	
-	/**
-	 * Perform inference of generic method type parameters and/or expected type
-	 */	
-	public static MethodBinding computeCompatibleMethod(MethodBinding originalMethod, TypeBinding[] arguments, Scope scope, InvocationSite invocationSite) {
-		
-		ParameterizedGenericMethodBinding methodSubstitute;
-		TypeVariableBinding[] typeVariables = originalMethod.typeVariables;
-		TypeBinding[] substitutes = invocationSite.genericTypeArguments();
-		
-		if (substitutes != null) {
-			if (substitutes.length != typeVariables.length) {
-		        // incompatible due to wrong arity
-		        return new ProblemMethodBinding(originalMethod, originalMethod.selector, substitutes, TypeParameterArityMismatch);
-			}
-			methodSubstitute = new ParameterizedGenericMethodBinding(originalMethod, substitutes, scope.environment());
-		} else {
-			// perform type inference based on argument types and expected type
-			
-			// collect substitutes by pattern matching parameters and arguments
-			TypeBinding[] parameters = originalMethod.parameters;
-			int varLength = typeVariables.length;
-			HashMap collectedSubstitutes = new HashMap(varLength);
-			for (int i = 0; i < varLength; i++)
-				collectedSubstitutes.put(typeVariables[i], new TypeBinding[1]);
-			
-			// collect argument type mapping, handling varargs
-			if (originalMethod.isVarargs()) {
-				int paramLength = parameters.length;
-				int minArgLength = paramLength - 1;
-				int argLength = arguments.length;
-				// process mandatory arguments
-				for (int i = 0; i < minArgLength; i++)
-					parameters[i].collectSubstitutes(arguments[i], collectedSubstitutes);
-				// process optional arguments
-				if (minArgLength < argLength) {
-					TypeBinding varargType = parameters[minArgLength]; // last arg type - as is ?
-					if (paramLength != argLength // argument is passed as is ?
-							||  (arguments[minArgLength] != NullBinding
-									&& (arguments[minArgLength].dimensions() != varargType.dimensions()))) { 
-						varargType = ((ArrayBinding)varargType).elementsType(); // eliminate one array dimension
-					}
-					for (int i = minArgLength; i < argLength; i++)
-						varargType.collectSubstitutes(arguments[i], collectedSubstitutes);
-				}
-			} else {
-				int paramLength = parameters.length;
-				for (int i = 0; i < paramLength; i++)
-					parameters[i].collectSubstitutes(arguments[i], collectedSubstitutes);
-			}
-			boolean needReturnTypeInference = false;
-			if (collectedSubstitutes.isEmpty()) {
-				// raw generic method inferred
-				methodSubstitute = new ParameterizedGenericMethodBinding(originalMethod, (RawTypeBinding)null, scope.environment());
-			} else {
-				substitutes = new TypeBinding[varLength];
-				for (int i = 0; i < varLength; i++) {
-					TypeBinding[] variableSubstitutes = (TypeBinding[]) collectedSubstitutes.get(typeVariables[i]);
-					TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(variableSubstitutes);
-					if (mostSpecificSubstitute == null)
-						return null; // incompatible
-					if (mostSpecificSubstitute == VoidBinding) {
-						needReturnTypeInference = true;
-					    mostSpecificSubstitute = typeVariables[i];
-					}				
-					substitutes[i] = mostSpecificSubstitute;
-				}
-				// apply inferred variable substitutions
-				methodSubstitute = new ParameterizedGenericMethodBinding(originalMethod, substitutes, scope.environment());
-			}
-	
-			if (needReturnTypeInference && invocationSite instanceof MessageSend) {
-				MessageSend message = (MessageSend) invocationSite;
-				TypeBinding expectedType = message.expectedType;
-				if (expectedType == null) {
-					// 15.12.2.8 - if no expected type, then assume Object
-					// actually it rather seems to handle the returned variable case by expecting its erasure instead
-					if (methodSubstitute.returnType.isTypeVariable()) {
-						expectedType = methodSubstitute.returnType.erasure();
-					} else {
-						expectedType =scope.getJavaLangObject(); 
-					}
-				}
-				methodSubstitute.inferFromExpectedType(expectedType, scope);
-			}
-		}
-		// check bounds
-		if (!methodSubstitute.isRaw) {
-			for (int i = 0, length = typeVariables.length; i < length; i++) {
-			    TypeVariableBinding typeVariable = typeVariables[i];
-			    TypeBinding substitute = substitutes[i];
-			    if (!typeVariable.boundCheck(methodSubstitute, substitute))
-			        // incompatible due to bound check
-			        return new ProblemMethodBinding(methodSubstitute, originalMethod.selector, new TypeBinding[]{substitutes[i], typeVariables[i] }, ParameterBoundMismatch);
-			}
-		}
+    
+    /**
+     * Create method of parameterized type, substituting original parameters with type arguments.
+     */
+	public ParameterizedGenericMethodBinding(MethodBinding originalMethod, TypeBinding[] typeArguments, LookupEnvironment environment) {
 
-		return methodSubstitute;
+	    this.environment = environment;
+		this.modifiers = originalMethod.modifiers;
+		this.selector = originalMethod.selector;
+		this.declaringClass = originalMethod.declaringClass;
+	    this.typeVariables = NoTypeVariables;
+	    this.typeArguments = typeArguments;
+	    this.isRaw = false;
+		this.isUnchecked = false;
+	    this.originalMethod = originalMethod;
+	    this.parameters = Scope.substitute(this, originalMethod.parameters);
+	    this.thrownExceptions = Scope.substitute(this, originalMethod.thrownExceptions);
+	    this.returnType = Scope.substitute(this, originalMethod.returnType);
+	    this.wasInferred = true;// resulting from method invocation inferrence
 	}
 
 	/*
 	 * parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature percent typeArguments
-	 * p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;TU;)V%<Lp/X;>
+	 * p.X<U> { <T> void bar(T t, U u) { new X<String>().bar(this, "") } } --> Lp/X<Ljava/lang/String;>;.bar<T:Ljava/lang/Object;>(TT;TU;)V^123%<Lp/X;>
 	 */
-	public char[] computeUniqueKey() {
+	public char[] computeUniqueKey(boolean withAccessFlags) {
 		if (this.isRaw)
-			return super.computeUniqueKey();
+			return super.computeUniqueKey(withAccessFlags);
 		StringBuffer buffer = new StringBuffer();
-		buffer.append(super.computeUniqueKey());
+		buffer.append(super.computeUniqueKey(withAccessFlags));
 		buffer.append('%');
 		buffer.append('<');
 		int length = this.typeArguments.length;
 		for (int i = 0; i < length; i++) {
 			TypeBinding typeArgument = this.typeArguments[i];
-			buffer.append(typeArgument.computeUniqueKey());
+			buffer.append(typeArgument.computeUniqueKey(false/*without access flags*/));
 		}
 		buffer.append('>');
 		int resultLength = buffer.length();
@@ -206,6 +333,12 @@
 	}
 	
 	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#environment()
+	 */
+	public LookupEnvironment environment() {
+		return this.environment;
+	}
+	/**
 	 * Returns true if some parameters got substituted.
 	 * NOTE: generic method invocation delegates to its declaring method (could be a parameterized one)
 	 */
@@ -220,151 +353,89 @@
 	 * NOTE: generic method invocation delegates to its declaring method (could be a parameterized one)
 	 */
 	public boolean hasSubstitutedReturnType() {
-		if (this.wasInferred) 
+		if (this.inferredReturnType) 
 			return this.originalMethod.hasSubstitutedReturnType();
 		return super.hasSubstitutedReturnType();
 	}
-	
-	public void inferFromExpectedType(TypeBinding expectedType, Scope scope) {
-	    if (this.returnType == expectedType) 
-	        return;
-	    if ((this.returnType.tagBits & TagBits.HasTypeVariable) == 0) 
-	        return;
-	    Map substitutes = new HashMap(1);
-	    int length = this.typeArguments.length;
-	    TypeVariableBinding[] originalVariables = this.original().typeVariables;
-	    boolean hasUnboundParameters = false;
-	    for (int i = 0; i < length; i++) {
-	        if (this.typeArguments[i] == originalVariables[i]) {
-	            hasUnboundParameters = true;
-	        	substitutes.put(originalVariables[i], new TypeBinding[1]);
-	        } else {
-	        	substitutes.put(originalVariables[i], new TypeBinding[] { this.typeArguments[i] });
-	        }
-	    }
-	    if (!hasUnboundParameters)
-	        return;
-	    returnType.collectSubstitutes(expectedType, substitutes);
-	    if (substitutes.isEmpty()) {
-	    	// raw generic method inferred
-	    	this.isRaw = true;
-	    	for (int i = 0; i < length; i++) {
-	    		this.typeArguments[i] = originalVariables[i].erasure();
-	    	}
-	    } else {
-			for (int i = 0; i < length; i++) {
-				TypeBinding[] variableSubstitutes = (TypeBinding[]) substitutes.get(originalVariables[i]);
-				TypeBinding mostSpecificSubstitute = scope.lowerUpperBound(variableSubstitutes);
-				if (mostSpecificSubstitute == null) {
-				    return; // TODO (philippe) should report no way to infer type
-				}
-				if (mostSpecificSubstitute == VoidBinding) {
-					// 15.12.2.8 - any remaining variable is assumed to be its erasure
-					mostSpecificSubstitute = originalVariables[i].erasure();
-				}				
-				this.typeArguments[i] = mostSpecificSubstitute;
+	/**
+	 * Given some type expectation, and type variable bounds, perform some inference.
+	 * Returns true if still had unresolved type variable at the end of the operation
+	 */
+	private ParameterizedGenericMethodBinding inferFromExpectedType(Scope scope, TypeBinding expectedType, Map collectedSubstitutes, TypeBinding[] substitutes) {
+	    TypeVariableBinding[] originalVariables = this.originalMethod.typeVariables; // immediate parent (could be a parameterized method)
+		int varLength = originalVariables.length;
+		
+		computeSubstitutes: {
+		    // infer from expected return type
+			if (expectedType != null) {
+			    returnType.collectSubstitutes(scope, expectedType, collectedSubstitutes, CONSTRAINT_SUPER);
 			}
-	    }
+		    // infer from bounds of type parameters
+			for (int i = 0; i < varLength; i++) {
+				TypeVariableBinding originalVariable = originalVariables[i];
+				TypeBinding argument = this.typeArguments[i];
+				if (originalVariable.firstBound == originalVariable.superclass) {
+					Scope.substitute(this, originalVariable.firstBound) // substitue original bound with resolved variables
+						.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
+				}
+				for (int j = 0, max = originalVariable.superInterfaces.length; j < max; j++) {
+					Scope.substitute(this, originalVariable.superInterfaces[j]) // substitue original bound with resolved variables
+						.collectSubstitutes(scope, argument, collectedSubstitutes, CONSTRAINT_EXTENDS);
+				}
+			}
+			substitutes = resolveSubstituteConstraints(scope, originalVariables, substitutes, true/*consider Ti<:Uk*/, collectedSubstitutes);
+			if (substitutes == null) 
+				return null; // incompatible
+			if (substitutes.length == 0) {
+		    	// raw generic method inferred
+		    	this.isRaw = true;
+				this.isUnchecked = false;
+		    	for (int i = 0; i < varLength; i++) {
+		    		this.typeArguments[i] = originalVariables[i].erasure();
+		    	}
+		    	break computeSubstitutes;
+			}
+			// this.typeArguments = substitutes; - no op since side effects got performed during #resolveSubstituteConstraints
+	    	for (int i = 0; i < varLength; i++) {
+	    		TypeBinding substitute = substitutes[i];
+	    		if (substitute != null) {
+	    			this.typeArguments[i] = substitutes[i];
+	    		} else {
+	    			// remaining unresolved variable are considered to be Object (or their bound actually)
+		    		this.typeArguments[i] = originalVariables[i].erasure();
+		    	}
+	    	}
+		}		
+		// adjust method types to reflect latest inference
 		TypeBinding oldReturnType = this.returnType;
-		this.returnType = this.substitute(this.returnType);
+		this.returnType = Scope.substitute(this, this.returnType);
 		this.inferredReturnType = this.returnType != oldReturnType;
 	    this.parameters = Scope.substitute(this, this.parameters);
 	    this.thrownExceptions = Scope.substitute(this, this.thrownExceptions);
+	    return this;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#isRawSubstitution()
+	 */
+	public boolean isRawSubstitution() {
+		return this.isRaw;
 	}
 	
-    /**
-	 * Returns a type, where original type was substituted using the receiver
-	 * parameterized method.
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#substitute(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding)
 	 */
-	public TypeBinding substitute(TypeBinding originalType) {
-	    
-		switch (originalType.kind()) {
-			
-			case Binding.TYPE_PARAMETER:
-		        TypeVariableBinding originalVariable = (TypeVariableBinding) originalType;
-		        TypeVariableBinding[] variables = this.originalMethod.typeVariables;
-		        int length = variables.length;
-		        // check this variable can be substituted given parameterized type
-		        if (originalVariable.rank < length && variables[originalVariable.rank] == originalVariable) {
-					return this.typeArguments[originalVariable.rank];
-		        }
-		        if (this.declaringClass instanceof Substitution) {
-		        	return ((Substitution)this.declaringClass).substitute(originalType);
-		        }
-		        break;
-	   		       
-			case Binding.PARAMETERIZED_TYPE:
-				ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType;
-				ReferenceBinding originalEnclosing = originalType.enclosingType();
-				ReferenceBinding substitutedEnclosing = originalEnclosing;
-				if (originalEnclosing != null) {
-					substitutedEnclosing = (ReferenceBinding) this.substitute(originalEnclosing);
-				}
-				if (this.isRaw) {
-					return this.environment.createRawType(originalParameterizedType.type, substitutedEnclosing);					
-				}
-				TypeBinding[] originalArguments = originalParameterizedType.arguments;
-				TypeBinding[] substitutedArguments = originalArguments;
-				if (originalArguments != null) {
-					substitutedArguments = Scope.substitute(this, originalArguments);
-				}
-				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
-					identicalVariables: { // if substituted with original variables, then answer the generic type itself
-						if (substitutedEnclosing != originalEnclosing) break identicalVariables;
-						TypeVariableBinding[] originalVariables = originalParameterizedType.type.typeVariables();
-						length = originalVariables.length;
-						for (int i = 0; i < length; i++) {
-							if (substitutedArguments[i] != originalVariables[i]) break identicalVariables;
-						}
-						return originalParameterizedType.type;
-					}
-					return this.environment.createParameterizedType(
-							originalParameterizedType.type, substitutedArguments, substitutedEnclosing);
-				}
-				break;   		        
-		        
-			case Binding.ARRAY_TYPE:
-				TypeBinding originalLeafComponentType = originalType.leafComponentType();
-				TypeBinding substitute = substitute(originalLeafComponentType); // substitute could itself be array type
-				if (substitute != originalLeafComponentType) {
-					return this.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions());
-				}
-				break;
-				
-			case Binding.WILDCARD_TYPE:
-		        WildcardBinding wildcard = (WildcardBinding) originalType;
-		        if (wildcard.kind != Wildcard.UNBOUND) {
-			        TypeBinding originalBound = wildcard.bound;
-			        TypeBinding substitutedBound = substitute(originalBound);
-			        if (substitutedBound != originalBound) {
-		        		return this.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, wildcard.kind);
-			        }
-		        }
-		        break;
-	
-	
-			case Binding.GENERIC_TYPE:
-			    // treat as if parameterized with its type variables
-				ReferenceBinding originalGenericType = (ReferenceBinding) originalType;
-				originalEnclosing = originalType.enclosingType();
-				substitutedEnclosing = originalEnclosing;
-				if (originalEnclosing != null) {
-					substitutedEnclosing = (ReferenceBinding) this.substitute(originalEnclosing);
-				}
-				if (this.isRaw) {
-					return this.environment.createRawType(originalGenericType, substitutedEnclosing);					
-				}				
-				TypeVariableBinding[] originalVariables = originalGenericType.typeVariables();
-				length = originalVariables.length;
-				System.arraycopy(originalVariables, 0, originalArguments = new TypeBinding[length], 0, length);
-				substitutedArguments = Scope.substitute(this, originalArguments);
-				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
-					return this.environment.createParameterizedType(
-							originalGenericType, substitutedArguments, substitutedEnclosing);
-				}
-				break;
-	    }
-	    return originalType;
+	public TypeBinding substitute(TypeVariableBinding originalVariable) {
+        TypeVariableBinding[] variables = this.originalMethod.typeVariables;
+        int length = variables.length;
+        // check this variable can be substituted given parameterized type
+        if (originalVariable.rank < length && variables[originalVariable.rank] == originalVariable) {
+			return this.typeArguments[originalVariable.rank];
+        }
+        if (!this.isStatic() && this.declaringClass instanceof Substitution) {
+        	return ((Substitution)this.declaringClass).substitute(originalVariable);
+        }
+	    return originalVariable;
 	}
 	/**
 	 * Returns the method to use during tiebreak (usually the method itself).
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
index bbe65e7..d3e82eb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,23 +25,70 @@
 	/**
 	 * Create method of parameterized type, substituting original parameters/exception/return type with type arguments.
 	 */
-	public ParameterizedMethodBinding(ParameterizedTypeBinding parameterizedDeclaringClass, MethodBinding originalMethod, boolean isStatic) {
+	public ParameterizedMethodBinding(final ParameterizedTypeBinding parameterizedDeclaringClass, MethodBinding originalMethod) {
 
 		super(
 				originalMethod.modifiers,
 				originalMethod.selector,
-				isStatic // no substitution if original was static
-						? originalMethod.returnType
-						: parameterizedDeclaringClass.substitute(originalMethod.returnType),
-				isStatic // no substitution if original was static
-					? originalMethod.parameters
-					: Scope.substitute(parameterizedDeclaringClass, originalMethod.parameters),
-				isStatic // no substitution if original was static
-					? originalMethod.thrownExceptions
-					: Scope.substitute(parameterizedDeclaringClass, originalMethod.thrownExceptions),
+				 originalMethod.returnType,
+				originalMethod.parameters,
+				originalMethod.thrownExceptions,
 				parameterizedDeclaringClass);
 		this.originalMethod = originalMethod;
-		this.typeVariables = originalMethod.typeVariables;
+
+		final TypeVariableBinding[] originalVariables = originalMethod.typeVariables;
+		Substitution substitution = null;
+		final int length = originalVariables.length;
+		final boolean isStatic = originalMethod.isStatic();
+		if (length == 0) {
+			this.typeVariables = NoTypeVariables;
+			if (!isStatic) substitution = parameterizedDeclaringClass;
+		} else {
+			// at least fix up the declaringElement binding + bound substitution if non static
+			final TypeVariableBinding[] substitutedVariables = new TypeVariableBinding[length];
+			for (int i = 0; i < length; i++) { // copy original type variable to relocate
+				TypeVariableBinding originalVariable = originalVariables[i];
+				substitutedVariables[i] = new TypeVariableBinding(originalVariable.sourceName, this, originalVariable.rank);
+			}
+			this.typeVariables = substitutedVariables;
+			
+			// need to substitute old var refs with new ones (double substitution: declaringClass + new type variables)
+			substitution = new Substitution() {
+				public LookupEnvironment environment() { 
+					return parameterizedDeclaringClass.environment; 
+				}
+				public boolean isRawSubstitution() {
+					return !isStatic && parameterizedDeclaringClass.isRawSubstitution();
+				}
+				public TypeBinding substitute(TypeVariableBinding typeVariable) {
+			        // check this variable can be substituted given copied variables
+			        if (typeVariable.rank < length && originalVariables[typeVariable.rank] == typeVariable) {
+						return substitutedVariables[typeVariable.rank];
+			        }
+			        if (!isStatic)
+						return parameterizedDeclaringClass.substitute(typeVariable);
+			        return typeVariable;
+				}
+			};
+		
+			// initialize new variable bounds
+			for (int i = 0; i < length; i++) {
+				TypeVariableBinding originalVariable = originalVariables[i];
+				TypeVariableBinding substitutedVariable = substitutedVariables[i];
+				substitutedVariable.superclass = (ReferenceBinding) Scope.substitute(substitution, originalVariable.superclass);
+				substitutedVariable.superInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
+				if (originalVariable.firstBound != null) {
+					substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
+						? substitutedVariable.superclass
+						: substitutedVariable.superInterfaces[0];
+				}
+			}
+		}
+		if (substitution != null) {
+			this.returnType = Scope.substitute(substitution, this.returnType);
+			this.parameters = Scope.substitute(substitution, this.parameters);
+			this.thrownExceptions = Scope.substitute(substitution, this.thrownExceptions);
+		}
 	}
 
 	public ParameterizedMethodBinding() {
@@ -50,10 +97,10 @@
 
 	/*
 	 * parameterizedDeclaringUniqueKey dot selector originalMethodGenericSignature
-	 * p.X<U> { void bar(U u) { new X<String>().bar("") } } --> Lp/X<Ljava/lang/String;>;.bar(TU;)V
+	 * p.X<U> { void bar(U u) { new X<String>().bar("") } } --> Lp/X<Ljava/lang/String;>;.bar(TU;)V^123
 	 */
-	public char[] computeUniqueKey() {
-		return computeUniqueKey(original());
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+		return computeUniqueKey(original(), withAccessFlags);
 	}
 
 	/**
@@ -71,7 +118,7 @@
 		ReferenceBinding genericClassType = scope.getJavaLangClass();
 		method.returnType = scope.createParameterizedType(
 			genericClassType,
-			new TypeBinding[] {  scope.environment().createWildcard(genericClassType, 0, receiverType.erasure(), Wildcard.EXTENDS) },
+			new TypeBinding[] {  scope.environment().createWildcard(genericClassType, 0, receiverType.erasure(), null /*no extra bound*/, Wildcard.EXTENDS) },
 			null);
 		return method;
 	}
@@ -96,4 +143,4 @@
 	public MethodBinding original() {
 		return this.originalMethod.original();
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
index e516714..1217d4c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000-2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -43,64 +43,99 @@
 				if (arguments[i] instanceof UnresolvedReferenceBinding)
 					((UnresolvedReferenceBinding) arguments[i]).addWrapper(this);
 		}
+		this.tagBits |=  HasUnresolvedTypeVariables; // cleared in resolve()
 	}
 
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#canBeInstantiated()
 	 */
 	public boolean canBeInstantiated() {
-		return ((this.tagBits & HasDirectWildcard) == 0) // cannot instantiate param type with wildcard arguments
-							&& super.canBeInstantiated();
+		return ((this.tagBits & HasDirectWildcard) == 0) && super.canBeInstantiated(); // cannot instantiate param type with wildcard arguments
 	}
 	public int kind() {
 		return PARAMETERIZED_TYPE;
 	}	
-	
+	/**
+	 * Perform capture conversion for a parameterized type with wildcard arguments
+	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#capture()
+	 */
+	public TypeBinding capture() {
+		TypeBinding[] originalArguments = arguments, capturedArguments = originalArguments;
+		if ((this.tagBits & TagBits.HasDirectWildcard) != 0) {
+			int length = originalArguments.length;
+			capturedArguments = new TypeBinding[length];
+			for (int i = 0; i < length; i++) {
+				TypeBinding argument = originalArguments[i];
+				if (argument.kind() == Binding.WILDCARD_TYPE) {
+					capturedArguments[i] = new CaptureBinding((WildcardBinding) argument);
+				} else {
+					capturedArguments[i] = argument;
+				}
+			}
+		}
+		if (capturedArguments != originalArguments) {
+			return this.environment.createParameterizedType(this.type, capturedArguments, enclosingType());
+		}
+		return this;
+	}
 	/**
 	 * Collect the substitutes into a map for certain type variables inside the receiver type
-	 * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
+	 * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
 	 */
-	public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
+	public void collectSubstitutes(Scope scope, TypeBinding otherType, Map substitutes, int constraint) {
+		
+		if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
+		if (otherType == NullBinding) return;
+	
 		if (this.arguments == null) return;
-		if (otherType instanceof ReferenceBinding) {
-			// allow List<T> to match with LinkedList<String>
-			ReferenceBinding equivalent = this;
-	        ReferenceBinding otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeErasingTo((ReferenceBinding)this.type.erasure());
-	        if (otherEquivalent == null) {
-	        	// allow LinkedList<String> to match List<T> (downcast scenario)
-		    	equivalent = this.findSuperTypeErasingTo((ReferenceBinding)otherType.erasure());
-	        	if (equivalent == null) return;
-	        	otherEquivalent = (ReferenceBinding)otherType;
-	        }
-	        TypeBinding[] elements;
-	        switch (equivalent.kind()) {
-	        	case Binding.GENERIC_TYPE :
-	        		elements = equivalent.typeVariables();
-	        		break;
-	        	case Binding.PARAMETERIZED_TYPE :
-	        		elements = ((ParameterizedTypeBinding)equivalent).arguments;
-	        		break;
-	        	default :
-	        		return;
-	        }
-	        TypeBinding[] otherElements;
-	        switch (otherEquivalent.kind()) {
-	        	case Binding.GENERIC_TYPE :
-	        		otherElements = otherEquivalent.typeVariables();
-	        		break;
-	        	case Binding.PARAMETERIZED_TYPE :
-	        		otherElements = ((ParameterizedTypeBinding)otherEquivalent).arguments;
-	        		break;
-	        	case Binding.RAW_TYPE :
-	        		substitutes.clear(); // clear all variables to indicate raw generic method in the end
-	        		return;
-	        	default :
-	        		return;
-	        }
-            for (int i = 0, length = elements.length; i < length; i++) {
-                elements[i].collectSubstitutes(otherElements[i], substitutes);
-	        }
-	    }
+		if (!(otherType instanceof ReferenceBinding)) return;
+		ReferenceBinding equivalent, otherEquivalent;
+		switch (constraint) {
+			case CONSTRAINT_EQUAL :
+			case CONSTRAINT_EXTENDS :
+				equivalent = this;
+		        otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeErasingTo((ReferenceBinding)this.type.erasure());
+		        if (otherEquivalent == null) return;
+		        break;
+			case CONSTRAINT_SUPER :
+	        default:
+		        equivalent = this.findSuperTypeErasingTo((ReferenceBinding)(otherType.erasure()));
+		        if (equivalent == null) return;
+		        otherEquivalent = (ReferenceBinding) otherType;
+		        break;
+		}
+        TypeBinding[] elements;
+        switch (equivalent.kind()) {
+        	case Binding.GENERIC_TYPE :
+        		elements = equivalent.typeVariables();
+        		break;
+        	case Binding.PARAMETERIZED_TYPE :
+        		elements = ((ParameterizedTypeBinding)equivalent).arguments;
+        		break;
+        	case Binding.RAW_TYPE :
+        		substitutes.clear(); // clear all variables to indicate raw generic method in the end
+        		return;
+        	default :
+        		return;
+        }
+        TypeBinding[] otherElements;
+        switch (otherEquivalent.kind()) {
+        	case Binding.GENERIC_TYPE :
+        		otherElements = otherEquivalent.typeVariables();
+        		break;
+        	case Binding.PARAMETERIZED_TYPE :
+        		otherElements = ((ParameterizedTypeBinding)otherEquivalent).arguments;
+        		break;
+        	case Binding.RAW_TYPE :
+        		substitutes.clear(); // clear all variables to indicate raw generic method in the end
+        		return;
+        	default :
+        		return;
+        }
+        for (int i = 0, length = elements.length; i < length; i++) {
+        	TypeBinding element = elements[i];
+            element.collectSubstitutes(scope, otherElements[i], substitutes, element.isWildcard() ? constraint : CONSTRAINT_EQUAL);
+        }
 	}
 	
 	/**
@@ -109,6 +144,44 @@
 	public void computeId() {
 		this.id = NoId;		
 	}
+	
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+	    StringBuffer sig = new StringBuffer(10);
+		if (this.isMemberType() && enclosingType().isParameterizedType()) {
+		    char[] typeSig = enclosingType().computeUniqueKey(false/*without access flags*/);
+		    for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
+		    sig.append('.').append(sourceName());
+		} else if(this.type.isLocalType()){
+			LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.type;
+			ReferenceBinding enclosing = localTypeBinding.enclosingType();
+			ReferenceBinding temp;
+			while ((temp = enclosing.enclosingType()) != null)
+				enclosing = temp;
+			char[] typeSig = enclosing.signature();
+		    for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
+			sig.append('$');
+			sig.append(localTypeBinding.sourceStart);
+		} else {
+		    char[] typeSig = this.type.signature();
+		    for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
+		}	   	    
+		if (this.arguments != null) {
+		    sig.append('<');
+		    for (int i = 0, length = this.arguments.length; i < length; i++) {
+		        sig.append(this.arguments[i].computeUniqueKey(false/*without access flags*/));
+		    }
+		    sig.append('>'); //$NON-NLS-1$
+		}
+		sig.append(';');
+		if (withAccessFlags) {
+			sig.append('^');
+			sig.append(getAccessFlags());
+		}
+		int sigLength = sig.length();
+		char[] uniqueKey = new char[sigLength];
+		sig.getChars(0, sigLength, uniqueKey, 0);			
+		return uniqueKey;
+   	}
 
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#constantPoolName()
@@ -118,7 +191,7 @@
 	}
 
 	public ParameterizedMethodBinding createParameterizedMethod(MethodBinding originalMethod) {
-		return new ParameterizedMethodBinding(this, originalMethod, originalMethod.isStatic());
+		return new ParameterizedMethodBinding(this, originalMethod);
 	}
 	
 	/**
@@ -145,13 +218,20 @@
 		if (this.isMemberType() && this.enclosingType == null) {
 			ReferenceBinding originalEnclosing = this.type.enclosingType();
 			this.enclosingType = originalEnclosing.isGenericType()
-													? this.environment.createRawType(originalEnclosing, originalEnclosing.enclosingType()) // TODO (need to propagate in depth on enclosing type)
-													: originalEnclosing;
+				? this.environment.createRawType(originalEnclosing, originalEnclosing.enclosingType()) // TODO (need to propagate in depth on enclosing type)
+				: originalEnclosing;
 		}
 	    return this.enclosingType;
 	}
 
 	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#environment()
+	 */
+	public LookupEnvironment environment() {
+		return this.environment;
+	}
+	
+	/**
      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
      */
     public TypeBinding erasure() {
@@ -168,20 +248,22 @@
 	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#fields()
 	 */
 	public FieldBinding[] fields() {
-		if (this.fields == null) {
-			try {
-				FieldBinding[] originalFields = this.type.fields();
-				int length = originalFields.length;
-				FieldBinding[] parameterizedFields = new FieldBinding[length];
-				for (int i = 0; i < length; i++)
-					// substitute all fields, so as to get updated declaring class at least
-					parameterizedFields[i] = new ParameterizedFieldBinding(this, originalFields[i]);
-				this.fields = parameterizedFields;	    
-			} finally {
-				// if the original fields cannot be retrieved (ex. AbortCompilation), then assume we do not have any fields
-				if (this.fields == null) 
-					this.fields = NoFields;
-			}
+		if ((tagBits & AreFieldsComplete) != 0)
+			return this.fields;
+
+		try {
+			FieldBinding[] originalFields = this.type.fields();
+			int length = originalFields.length;
+			FieldBinding[] parameterizedFields = new FieldBinding[length];
+			for (int i = 0; i < length; i++)
+				// substitute all fields, so as to get updated declaring class at least
+				parameterizedFields[i] = new ParameterizedFieldBinding(this, originalFields[i]);
+			this.fields = parameterizedFields;	    
+		} finally {
+			// if the original fields cannot be retrieved (ex. AbortCompilation), then assume we do not have any fields
+			if (this.fields == null) 
+				this.fields = NoFields;
+			tagBits |= AreFieldsComplete;
 		}
 		return this.fields;
 	}
@@ -229,7 +311,7 @@
 	public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
 		int argCount = argumentTypes.length;
 
-		if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
+		if ((tagBits & AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
 			nextMethod : for (int m = methods.length; --m >= 0;) {
 				MethodBinding method = methods[m];
 				if (method.selector == TypeConstants.INIT && method.parameters.length == argCount) {
@@ -257,7 +339,7 @@
 	}
 
 	/**
-	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getExactMethod(char[], TypeBinding[])
+	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#getExactMethod(char[], TypeBinding[],CompilationUnitScope)
 	 */
 	public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
 		// sender from refScope calls recordTypeReference(this)
@@ -266,7 +348,7 @@
 		boolean foundNothing = true;
 		MethodBinding match = null;
 
-		if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
+		if ((tagBits & AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
 			nextMethod : for (int m = methods.length; --m >= 0;) {
 				MethodBinding method = methods[m];
 				if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) {
@@ -296,9 +378,13 @@
 				}
 			}
 		}
-		if (match != null) return match;
-
-		if (foundNothing) {
+		if (match != null) {
+			// cannot be picked up as an exact match if its a possible anonymous case
+			if (match.hasSubstitutedParameters() && this.arguments != null && this.arguments.length > 1) return null;
+			return match;
+		}
+	
+		if (foundNothing && (this.arguments == null || this.arguments.length <= 1)) {
 			if (isInterface()) {
 				 if (superInterfaces().length == 1) {
 					if (refScope != null)
@@ -363,7 +449,8 @@
 				return result;
 			}
 		}
-		if ((modifiers & AccUnresolved) == 0) return NoMethods; // have created all the methods and there are no matches
+		if ((tagBits & AreMethodsComplete) != 0)
+			return NoMethods; // have created all the methods and there are no matches
 
 		MethodBinding[] parameterizedMethods = null;
 		try {
@@ -392,6 +479,7 @@
 		        this.methods = parameterizedMethods = NoMethods;
 		}
 	}
+
 	public boolean hasMemberTypes() {
 	    return this.type.hasMemberTypes();
 	}
@@ -414,7 +502,7 @@
 		// this.superInterfaces = null;
 		// this.fields = null;
 		// this.methods = null;		
-		this.modifiers = someType.modifiers | AccGenericSignature | AccUnresolved; // until methods() is sent
+		this.modifiers = someType.modifiers | AccGenericSignature;
 		if (someArguments != null) {
 			this.arguments = someArguments;
 			for (int i = 0, length = someArguments.length; i < length; i++) {
@@ -423,13 +511,14 @@
 				if (isWildcardArgument) {
 					this.tagBits |= HasDirectWildcard;
 				}
-				if (!isWildcardArgument || ((WildcardBinding) someArgument).kind != Wildcard.UNBOUND) {
+				if (!isWildcardArgument || ((WildcardBinding) someArgument).boundKind != Wildcard.UNBOUND) {
 					this.tagBits |= IsBoundParameterizedType;
 				}
-			    this.tagBits |= someArgument.tagBits & (HasTypeVariable);
+			    this.tagBits |= someArgument.tagBits & HasTypeVariable;
 			}
 		}	    
 		this.tagBits |= someType.tagBits & (IsLocalType| IsMemberType | IsNestedType);
+		this.tagBits &= ~(AreFieldsComplete|AreMethodsComplete);
 	}
 
 	protected void initializeArguments() {
@@ -482,6 +571,13 @@
 	}
 	
 	/**
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#isRawSubstitution()
+	 */
+	public boolean isRawSubstitution() {
+		return isRawType();
+	}
+	
+	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#memberTypes()
 	 */
 	public ReferenceBinding[] memberTypes() {
@@ -507,7 +603,7 @@
 	 * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#methods()
 	 */
 	public MethodBinding[] methods() {
-		if ((modifiers & AccUnresolved) == 0)
+		if ((tagBits & AreMethodsComplete) != 0)
 			return this.methods;
 
 		try {
@@ -523,7 +619,7 @@
 		    if (this.methods == null) 
 		        this.methods = NoMethods;
 
-			modifiers &= ~AccUnresolved;
+			tagBits |=  AreMethodsComplete;
 		}		
 		return this.methods;
 	}
@@ -560,7 +656,10 @@
 	}
 
 	ReferenceBinding resolve() {
-		// TODO need flag to know that this has already been done... should it be on ReferenceBinding?
+		if ((this.tagBits & HasUnresolvedTypeVariables) == 0)
+			return this;
+
+		this.tagBits &= ~HasUnresolvedTypeVariables; // can be recursive so only want to call once
 		ReferenceBinding resolvedType = BinaryTypeBinding.resolveType(this.type, this.environment, false); // still part of parameterized type ref
 		if (this.arguments != null) {
 			int argLength = this.arguments.length;
@@ -578,7 +677,7 @@
 			// check argument type compatibility
 			for (int i = 0; i < argLength; i++) {
 			    TypeBinding resolvedArgument = this.arguments[i];
-				if (!refTypeVariables[i].boundCheck(this, resolvedArgument)) {
+				if (refTypeVariables[i].boundCheck(this, resolvedArgument) != TypeConstants.OK) {
 					this.environment.problemReporter.typeMismatchError(resolvedArgument, refTypeVariables[i], resolvedType, null);
 			    }
 			}
@@ -609,6 +708,7 @@
 		nameBuffer.getChars(0, nameLength, shortReadableName, 0);	    
 	    return shortReadableName;
 	}
+
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#signature()
 	 */
@@ -627,97 +727,30 @@
 	}
 
 	/**
-	 * Returns a type, where original type was substituted using the receiver
-	 * parameterized type.
+	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#substitute(org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding)
 	 */
-	public TypeBinding substitute(TypeBinding originalType) {
+	public TypeBinding substitute(TypeVariableBinding originalVariable) {
 		
-		switch (originalType.kind()) {
-			
-			case Binding.TYPE_PARAMETER:
-				TypeVariableBinding originalVariable = (TypeVariableBinding) originalType;
-				ParameterizedTypeBinding currentType = this;
-				while (true) {
-					if (currentType.arguments != null) {
-						TypeVariableBinding[] typeVariables = currentType.type.typeVariables();
-						int length = typeVariables.length;
-						// check this variable can be substituted given parameterized type
-						if (originalVariable.rank < length && typeVariables[originalVariable.rank] == originalVariable) {
-							return currentType.arguments[originalVariable.rank];
-						}
-					}
-					// recurse on enclosing type, as it may hold more substitutions to perform
-					ReferenceBinding enclosing = currentType.enclosingType();
-					if (!(enclosing instanceof ParameterizedTypeBinding))
-						break;
-					currentType = (ParameterizedTypeBinding) enclosing;
-				}
+		ParameterizedTypeBinding currentType = this;
+		while (true) {
+			TypeVariableBinding[] typeVariables = currentType.type.typeVariables();
+			int length = typeVariables.length;
+			// check this variable can be substituted given parameterized type
+			if (originalVariable.rank < length && typeVariables[originalVariable.rank] == originalVariable) {
+			    // lazy init, since cannot do so during binding creation if during supertype connection
+			    if (currentType.arguments == null)
+					currentType.initializeArguments(); // only for raw types
+			    if (currentType.arguments != null)
+					return currentType.arguments[originalVariable.rank];
+			}
+			// recurse on enclosing type, as it may hold more substitutions to perform
+			if (currentType.isStatic()) break;
+			ReferenceBinding enclosing = currentType.enclosingType();
+			if (!(enclosing instanceof ParameterizedTypeBinding))
 				break;
-				
-			case Binding.PARAMETERIZED_TYPE:
-				ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType;
-				ReferenceBinding originalEnclosing = originalType.enclosingType();
-				ReferenceBinding substitutedEnclosing = originalEnclosing;
-				if (originalEnclosing != null) {
-					substitutedEnclosing = (ReferenceBinding) this.substitute(originalEnclosing);
-				}
-				TypeBinding[] originalArguments = originalParameterizedType.arguments;
-				TypeBinding[] substitutedArguments = originalArguments;
-				if (originalArguments != null) {
-					substitutedArguments = Scope.substitute(this, originalArguments);
-				}
-				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
-					identicalVariables: { // if substituted with original variables, then answer the generic type itself
-						if (substitutedEnclosing != originalEnclosing) break identicalVariables;
-						TypeVariableBinding[] originalVariables = originalParameterizedType.type.typeVariables();
-						for (int i = 0, length = originalVariables.length; i < length; i++) {
-							if (substitutedArguments[i] != originalVariables[i]) break identicalVariables;
-						}
-						return originalParameterizedType.type;
-					}
-					return this.environment.createParameterizedType(
-							originalParameterizedType.type, substitutedArguments, substitutedEnclosing);
-				}
-				break;
-				
-			case Binding.ARRAY_TYPE:
-				TypeBinding originalLeafComponentType = originalType.leafComponentType();
-				TypeBinding substitute = substitute(originalLeafComponentType); // substitute could itself be array type
-				if (substitute != originalLeafComponentType) {
-					return this.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions());
-				}
-				break;
-
-			case Binding.WILDCARD_TYPE:
-		        WildcardBinding wildcard = (WildcardBinding) originalType;
-		        if (wildcard.kind != Wildcard.UNBOUND) {
-			        TypeBinding originalBound = wildcard.bound;
-			        TypeBinding substitutedBound = substitute(originalBound);
-			        if (substitutedBound != originalBound) {
-		        		return this.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, wildcard.kind);
-			        }
-		        }
-				break;
-
-			case Binding.GENERIC_TYPE:
-			    // treat as if parameterized with its type variables
-				ReferenceBinding originalGenericType = (ReferenceBinding) originalType;
-				originalEnclosing = originalType.enclosingType();
-				substitutedEnclosing = originalEnclosing;
-				if (originalEnclosing != null) {
-					substitutedEnclosing = (ReferenceBinding) this.substitute(originalEnclosing);
-				}
-				TypeVariableBinding[] originalVariables = originalGenericType.typeVariables();
-				int length = originalVariables.length;
-				System.arraycopy(originalVariables, 0, originalArguments = new TypeBinding[length], 0, length);
-				substitutedArguments = Scope.substitute(this, originalArguments);
-				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
-					return this.environment.createParameterizedType(
-							originalGenericType, substitutedArguments, substitutedEnclosing);
-				}
-				break;
+			currentType = (ParameterizedTypeBinding) enclosing;
 		}
-		return originalType;
+		return originalVariable;
 	}	
 
 	/**
@@ -728,7 +761,7 @@
 	        // note: Object cannot be generic
 	        ReferenceBinding genericSuperclass = this.type.superclass();
 	        if (genericSuperclass == null) return null; // e.g. interfaces
-		    this.superclass = (ReferenceBinding) substitute(genericSuperclass);
+		    this.superclass = (ReferenceBinding) Scope.substitute(this, genericSuperclass);
 	    }
 		return this.superclass;
 	}
@@ -853,6 +886,7 @@
 		return buffer.toString();
 		
 	}
+
 	public TypeVariableBinding[] typeVariables() {
 		if (this.arguments == null) {
 			// retain original type variables if not substituted (member type of parameterized type)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java
index b1dd4db..334a72d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
index ec3012d..0410c5c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java
index e5ae8db..fd3498a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java
index c2b2367..2ab2264 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java
index 97570b7..2031d61 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
index 00d8a18..a4a3985 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
index ce950e2..352de0d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java
@@ -1,17 +1,16 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 
 /**
  * Denote a raw type, i.e. a generic type referenced without any type arguments.
@@ -30,6 +29,27 @@
 		if (enclosingType == null || (enclosingType.modifiers & AccGenericSignature) == 0)
 			this.modifiers &= ~AccGenericSignature; // only need signature if enclosing needs one
 	}    
+	
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+	    StringBuffer sig = new StringBuffer(10);
+		if (isMemberType() && enclosingType().isParameterizedType()) {
+		    char[] typeSig = enclosingType().computeUniqueKey(false/*without access flags*/);
+		    for (int i = 0; i < typeSig.length-1; i++) sig.append(typeSig[i]); // copy all but trailing semicolon
+		    sig.append('.').append(sourceName()).append('<').append('>').append(';');
+		} else {
+		     sig.append(this.type.signature()); // erasure
+		     sig.insert(sig.length()-1, "<>"); //$NON-NLS-1$
+		}
+		if (withAccessFlags) {
+			sig.append('^');
+			sig.append(getAccessFlags());
+		}
+		int sigLength = sig.length();
+		char[] uniqueKey = new char[sigLength];
+		sig.getChars(0, sigLength, uniqueKey, 0);						    
+		return uniqueKey;
+   	}
+	
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding#createParameterizedMethod(org.eclipse.jdt.internal.compiler.lookup.MethodBinding)
 	 */
@@ -76,12 +96,22 @@
 	}		
 	
     public boolean isEquivalentTo(TypeBinding otherType) {
-	    if (this == otherType) return true;
-        if (otherType == null) return false;
-		if (otherType.isWildcard()) // wildcard
-			return ((WildcardBinding) otherType).boundCheck(this);
-        return otherType.erasure() == this.erasure();
-    }
+		if (this == otherType) 
+		    return true;
+	    if (otherType == null) 
+	        return false;
+	    switch(otherType.kind()) {
+	
+	    	case Binding.WILDCARD_TYPE :
+	        	return ((WildcardBinding) otherType).boundCheck(this);
+	    		
+	    	case Binding.GENERIC_TYPE :
+	    	case Binding.PARAMETERIZED_TYPE :
+	    	case Binding.RAW_TYPE :
+	            return erasure() == otherType.erasure();
+	    }
+        return false;
+	}
 	/**
 	 * Raw type is not treated as a standard parameterized type
 	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#isParameterizedType()
@@ -116,78 +146,6 @@
 	}
 
 	/**
-	 * Returns a type, where original type was substituted using the receiver
-	 * raw type.
-	 * On raw types, all parameterized type denoting same original type are converted
-	 * to raw types. e.g. 
-	 * class X <T> {
-	 *   X<T> foo;
-	 *   X<String> bar;
-	 * } when used in raw fashion, then type of both foo and bar is raw type X.
-	 */
-	public TypeBinding substitute(TypeBinding originalType) {
-	    
-		switch (originalType.kind()) {
-			
-			case Binding.TYPE_PARAMETER:
-		        TypeVariableBinding originalVariable = (TypeVariableBinding) originalType;
-			    ParameterizedTypeBinding currentType = this;
-		        while (true) {
-			        TypeVariableBinding[] typeVariables = currentType.type.typeVariables();
-			        int length = typeVariables.length;
-			        // check this variable can be substituted given parameterized type
-			        if (originalVariable.rank < length && typeVariables[originalVariable.rank] == originalVariable) {
-					    // lazy init, since cannot do so during binding creation if during supertype connection
-					    if (currentType.arguments == null)  currentType.initializeArguments();
-					    if (currentType.arguments != null)
-				           return currentType.arguments[originalVariable.rank];
-			        }
-				    // recurse on enclosing type, as it may hold more substitutions to perform
-				    ReferenceBinding enclosing = currentType.enclosingType();
-				    if (!(enclosing instanceof ParameterizedTypeBinding))
-				        break;
-				    currentType = (ParameterizedTypeBinding) enclosing;
-		        }
-		        break;
-		        
-			case Binding.PARAMETERIZED_TYPE:
-				ReferenceBinding substitutedEnclosing = originalType.enclosingType();
-				if (substitutedEnclosing != null) {
-					substitutedEnclosing = (ReferenceBinding) this.substitute(substitutedEnclosing);
-				}				
-		        ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType;
-				return this.environment.createRawType(originalParameterizedType.type, substitutedEnclosing);
-				
-			case Binding.GENERIC_TYPE:
-				substitutedEnclosing = originalType.enclosingType();
-				if (substitutedEnclosing != null) {
-					substitutedEnclosing = (ReferenceBinding) this.substitute(substitutedEnclosing);
-				}				
-	            return this.environment.createRawType((ReferenceBinding)originalType, substitutedEnclosing);
-	            
-			case Binding.WILDCARD_TYPE:
-		        WildcardBinding wildcard = (WildcardBinding) originalType;
-		        if (wildcard.kind != Wildcard.UNBOUND) {
-			        TypeBinding originalBound = wildcard.bound;
-			        TypeBinding substitutedBound = substitute(originalBound);
-			        if (substitutedBound != originalBound) {
-		        		return this.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, wildcard.kind);
-			        }
-		        }
-		        break;
-		        
-			case Binding.ARRAY_TYPE:
-				TypeBinding originalLeafComponentType = originalType.leafComponentType();
-				TypeBinding substitute = substitute(originalLeafComponentType); // substitute could itself be array type
-				if (substitute != originalLeafComponentType) {
-					return this.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions());
-				}
-				break;
-	    }
-	    return originalType;
-	}	
-
-	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
 	 */
 	public char[] shortReadableName() /*Object*/ {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
index f4912d1..2b3456f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java
@@ -1,16 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
 import org.eclipse.jdt.internal.compiler.env.IDependent;
 
 /*
@@ -25,6 +26,9 @@
 */
 
 abstract public class ReferenceBinding extends TypeBinding implements IDependent {
+	
+	public static ReferenceBinding LUB_GENERIC = new ReferenceBinding() { /* used for lub computation */};
+	
 	public char[][] compoundName;
 	public char[] sourceName;
 	public int modifiers;
@@ -77,11 +81,13 @@
 
 		ReferenceBinding currentType = invocationType;
 		ReferenceBinding declaringClass = enclosingType(); // protected types always have an enclosing one
+		if (declaringClass == invocationType) return true;
+
+		ReferenceBinding declaringErasure = (ReferenceBinding) declaringClass.erasure();
 		if (declaringClass == null) return false; // could be null if incorrect top-level protected type
 		//int depth = 0;
 		do {
-			if (declaringClass == invocationType) return true;
-			if (declaringClass.isSuperclassOf(currentType)) return true;
+			if (currentType.findSuperTypeErasingTo(declaringErasure) != null) return true;
 			//depth++;
 			currentType = currentType.enclosingType();
 		} while (currentType != null);
@@ -192,6 +198,26 @@
 	// isDefault()
 	return invocationType.fPackage == fPackage;
 }
+public char[] computeGenericTypeSignature(TypeVariableBinding[] typeVariables) {
+    if (typeVariables == NoTypeVariables) {
+        return signature();
+    } else {
+	    char[] typeSig = signature();
+	    StringBuffer sig = new StringBuffer(10);
+	    for (int i = 0; i < typeSig.length-1; i++) { // copy all but trailing semicolon
+	    	sig.append(typeSig[i]);
+	    }
+	    sig.append('<');
+	    for (int i = 0, length = typeVariables.length; i < length; i++) {
+	        sig.append(typeVariables[i].genericTypeSignature());
+	    }
+	    sig.append(">;"); //$NON-NLS-1$
+		int sigLength = sig.length();
+		char[] result = new char[sigLength];
+		sig.getChars(0, sigLength, result, 0);
+		return result;
+    }
+}
 public void computeId() {
 	
 	switch (compoundName.length) {
@@ -346,13 +372,37 @@
 			break;
 	}
 }
+/*
+ * p.X<T extends Y & I, U extends Y> {} -> Lp/X<TT;TU;>;^123
+ */
+public char[] computeUniqueKey(boolean withAccessFlags) {
+	// generic type signature
+	char[] genericSignature = genericTypeSignature();
+	int sigLength = genericSignature.length;
+	
+	if (!withAccessFlags) return genericSignature;
+	
+	// flags
+	String flags = Integer.toString(getAccessFlags());
+	int flagsLength = flags.length();
+	
+	// unique key
+	char[] uniqueKey = new char[sigLength + 1 + flagsLength];
+	int index = 0;
+	System.arraycopy(genericSignature, 0, uniqueKey, index, sigLength);
+	index += sigLength;
+	uniqueKey[index++] = '^';
+	flags.getChars(0, flagsLength, uniqueKey, index);
+	
+	return uniqueKey;
+}
 /* Answer the receiver's constant pool name.
 *
 * NOTE: This method should only be used during/after code gen.
 */
 
 public char[] constantPoolName() /* java/lang/Object */ {
-	if (constantPoolName != null) 	return constantPoolName;
+	if (constantPoolName != null) return constantPoolName;
 	return constantPoolName = CharOperation.concatWith(compoundName, '/');
 }
 public String debugName() {
@@ -365,12 +415,39 @@
 		depth++;
 	return depth;
 }
+public boolean detectAnnotationCycle() {
+	if ((this.tagBits & TagBits.EndAnnotationCheck) != 0) return false; // already checked
+	if ((this.tagBits & TagBits.BeginAnnotationCheck) != 0) return true; // in the middle of checking its methods
+
+	this.tagBits |= TagBits.BeginAnnotationCheck;
+	MethodBinding[] currentMethods = methods();
+	for (int i = 0, l = currentMethods.length; i < l; i++) {
+		TypeBinding returnType = currentMethods[i].returnType.leafComponentType();
+		if (returnType.isAnnotationType() && ((ReferenceBinding) returnType).detectAnnotationCycle()) {
+			if (this instanceof SourceTypeBinding) {
+				MethodDeclaration decl = (MethodDeclaration) currentMethods[i].sourceMethod();
+				((SourceTypeBinding) this).scope.problemReporter().annotationCircularity(this, returnType, decl != null ? decl.returnType : null);
+			}
+			return true;
+		}
+	}
+	this.tagBits |= TagBits.EndAnnotationCheck;
+	return false;
+}
 public final ReferenceBinding enclosingTypeAt(int relativeDepth) {
 	ReferenceBinding current = this;
 	while (relativeDepth-- > 0 && current != null)
 		current = current.enclosingType();
 	return current;
 }
+public int enumConstantCount() {
+	int count = 0;
+	FieldBinding[] fields = fields();
+	for (int i = 0, length = fields.length; i < length; i++) {
+		if ((fields[i].modifiers & AccEnum) != 0) count++;
+	}
+	return count;
+}
 public int fieldCount() {
 	return fields().length;
 }
@@ -429,7 +506,7 @@
 
     if (this == erasure || erasure() == erasure) return this;
     ReferenceBinding currentType = this;
-    if (erasure.isClass()) {
+    if (!erasure.isInterface()) {
 		while ((currentType = currentType.superclass()) != null) {
 			if (currentType == erasure || currentType.erasure() == erasure) return currentType;
 		}
@@ -477,9 +554,7 @@
 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
 	return null;
 }
-public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes) {
-	return getExactMethod(selector, argumentTypes, null);
-}
+
 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
 	return null;
 }
@@ -605,22 +680,37 @@
 */
 public boolean isCompatibleWith(TypeBinding otherType) {
     
-	if (otherType == this)
+	if (otherType == this) 
 		return true;
-	if (otherType.id == T_JavaLangObject)
+	if (otherType.id == T_JavaLangObject) 
 		return true;
-	if (!(otherType instanceof ReferenceBinding))
-		return false;
-	ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
-	if (this.isEquivalentTo(otherReferenceType)) return true;
-	if (otherReferenceType.isWildcard()) {
-		return false; // should have passed equivalence check above if wildcard
+	// equivalence may allow compatibility with array type through wildcard bound
+	if (this.isEquivalentTo(otherType)) 
+		return true;
+	switch (otherType.kind()) {
+		case Binding.WILDCARD_TYPE :
+			return false; // should have passed equivalence check above if wildcard
+		case Binding.TYPE_PARAMETER :
+			// check compatibility with capture of ? super X
+			if (otherType.isCapture()) {
+				CaptureBinding otherCapture = (CaptureBinding) otherType;
+				if (otherCapture.lowerBound != null) {
+					return this.isCompatibleWith(otherCapture.lowerBound);
+				}
+			}
+		case Binding.GENERIC_TYPE :
+		case Binding.TYPE :
+		case Binding.PARAMETERIZED_TYPE :
+		case Binding.RAW_TYPE :
+			ReferenceBinding otherReferenceType = (ReferenceBinding) otherType;
+			if (otherReferenceType.isInterface()) // could be annotation type
+				return implementsInterface(otherReferenceType, true);
+			if (this.isInterface())  // Explicit conversion from an interface to a class is not allowed
+				return false;
+			return otherReferenceType.isSuperclassOf(this);
+		default :
+			return false;
 	}
-	if (otherReferenceType.isInterface())
-		return implementsInterface(otherReferenceType, true);
-	if (isInterface())  // Explicit conversion from an interface to a class is not allowed
-		return false;
-	return otherReferenceType.isSuperclassOf(this);
 }
 
 /* Answer true if the receiver has default visibility
@@ -643,8 +733,20 @@
 	return (modifiers & AccFinal) != 0;
 }
 public boolean isInterface() {
-	// only consider strict interfaces
-	return (modifiers & (AccInterface | AccAnnotation)) == AccInterface;
+	// consider strict interfaces and annotation types
+	return (modifiers & AccInterface) != 0;
+}
+	
+public final boolean isPartOfRawType() {
+	ReferenceBinding current = this;
+	do {
+		if (current.isRawType())
+			return true;
+		// no static type
+		if (isStatic()) 
+			break;
+	} while ((current = current.enclosingType()) != null);
+    return false;
 }
 
 /* Answer true if the receiver has private visibility
@@ -674,8 +776,7 @@
  */
 
 public final boolean isStatic() {
-	return (modifiers & (AccStatic | AccInterface)) != 0 ||
-		    (tagBits & IsNestedType) == 0;
+	return (modifiers & (AccStatic | AccInterface)) != 0 || (tagBits & IsNestedType) == 0;
 }
 /* Answer true if all float operations must adher to IEEE 754 float/double rules
 */
@@ -699,35 +800,23 @@
 */
 
 public final boolean isViewedAsDeprecated() {
-	return (modifiers & AccDeprecated) != 0 ||
-		(modifiers & AccDeprecatedImplicitly) != 0;
+	return (modifiers & (AccDeprecated | AccDeprecatedImplicitly)) != 0;
 }
 public ReferenceBinding[] memberTypes() {
 	return NoMemberTypes;
 }
 
-/**
- * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
- */
-public boolean needsUncheckedConversion(TypeBinding targetType) {
-	if (this == targetType) return false;
-	if (!(targetType instanceof ReferenceBinding)) 
-		return false;
-	TypeBinding compatible = this.findSuperTypeErasingTo((ReferenceBinding)targetType.erasure());
-	if (compatible == null) 
-		return false;
-	if (!compatible.isPartOfRawType()) return false;
-	do {
-		if (compatible.isRawType() && (targetType.isBoundParameterizedType() || targetType.isGenericType())) {
-			return true;
-		}
-	} while ((compatible = compatible.enclosingType()) != null && (targetType = targetType.enclosingType()) != null);
-	return false;
-}
-
 public MethodBinding[] methods() {
 	return NoMethods;
 }
+public final ReferenceBinding outermostEnclosingType() {
+	ReferenceBinding current = this;
+	while (true) {
+		ReferenceBinding last = current;
+		if ((current = current.enclosingType()) == null) 
+			return last;
+	}
+}
 /**
 * Answer the source name for the type.
 * In the case of member types, as the qualified name from its top level type.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 9b0209f..32000e8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,8 +12,11 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.*;
@@ -26,7 +29,7 @@
 
 public abstract class Scope
 	implements BaseTypes, CompilerModifiers, ProblemReasons, TagBits, TypeConstants, TypeIds {
-
+	
 	public final static int BLOCK_SCOPE = 1;
 	public final static int CLASS_SCOPE = 3;
 	public final static int COMPILATION_UNIT_SCOPE = 4;
@@ -37,6 +40,9 @@
 	public final static int AUTOBOX_COMPATIBLE = 1;
 	public final static int VARARGS_COMPATIBLE = 2;
 
+	public int kind;
+	public Scope parent;
+
    /* Answer an int describing the relationship between the given types.
 	*
 	* 		NotRelated 
@@ -50,16 +56,79 @@
 			return MoreGeneric;
 		return NotRelated;
 	}
-
+	
+	public static TypeBinding getBaseType(char[] name) {
+		// list should be optimized (with most often used first)
+		int length = name.length;
+		if (length > 2 && length < 8) {
+			switch (name[0]) {
+				case 'i' :
+					if (length == 3 && name[1] == 'n' && name[2] == 't')
+						return IntBinding;
+					break;
+				case 'v' :
+					if (length == 4 && name[1] == 'o' && name[2] == 'i' && name[3] == 'd')
+						return VoidBinding;
+					break;
+				case 'b' :
+					if (length == 7
+						&& name[1] == 'o'
+						&& name[2] == 'o'
+						&& name[3] == 'l'
+						&& name[4] == 'e'
+						&& name[5] == 'a'
+						&& name[6] == 'n')
+						return BooleanBinding;
+					if (length == 4 && name[1] == 'y' && name[2] == 't' && name[3] == 'e')
+						return ByteBinding;
+					break;
+				case 'c' :
+					if (length == 4 && name[1] == 'h' && name[2] == 'a' && name[3] == 'r')
+						return CharBinding;
+					break;
+				case 'd' :
+					if (length == 6
+						&& name[1] == 'o'
+						&& name[2] == 'u'
+						&& name[3] == 'b'
+						&& name[4] == 'l'
+						&& name[5] == 'e')
+						return DoubleBinding;
+					break;
+				case 'f' :
+					if (length == 5
+						&& name[1] == 'l'
+						&& name[2] == 'o'
+						&& name[3] == 'a'
+						&& name[4] == 't')
+						return FloatBinding;
+					break;
+				case 'l' :
+					if (length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g')
+						return LongBinding;
+					break;
+				case 's' :
+					if (length == 5
+						&& name[1] == 'h'
+						&& name[2] == 'o'
+						&& name[3] == 'r'
+						&& name[4] == 't')
+						return ShortBinding;
+			}
+		}
+		return null;
+	}
+	
 	/**
 	 * Returns an array of types, where original types got substituted given a substitution.
 	 * Only allocate an array if anything is different.
 	 */
 	public static ReferenceBinding[] substitute(Substitution substitution, ReferenceBinding[] originalTypes) {
+		if (originalTypes == null) return null;
 	    ReferenceBinding[] substitutedTypes = originalTypes;
 	    for (int i = 0, length = originalTypes.length; i < length; i++) {
 	        ReferenceBinding originalType = originalTypes[i];
-	        ReferenceBinding substitutedParameter = (ReferenceBinding)substitution.substitute(originalType);
+	        ReferenceBinding substitutedParameter = (ReferenceBinding)substitute(substitution, originalType);
 	        if (substitutedParameter != originalType) {
 	            if (substitutedTypes == originalTypes) {
 	                System.arraycopy(originalTypes, 0, substitutedTypes = new ReferenceBinding[length], 0, i);
@@ -73,14 +142,112 @@
 	}
 
 	/**
+	 * Returns a type, where original type was substituted using the receiver
+	 * parameterized type.
+	 * In raw mode, all parameterized type denoting same original type are converted
+	 * to raw types. e.g. 
+	 * class X <T> {
+	 *   X<T> foo;
+	 *   X<String> bar;
+	 * } when used in raw fashion, then type of both foo and bar is raw type X.
+	 * 
+	 */
+	public static TypeBinding substitute(Substitution substitution, TypeBinding originalType) {
+		
+		switch (originalType.kind()) {
+			
+			case Binding.TYPE_PARAMETER:
+				return substitution.substitute( (TypeVariableBinding) originalType);
+				
+			case Binding.PARAMETERIZED_TYPE:
+				ParameterizedTypeBinding originalParameterizedType = (ParameterizedTypeBinding) originalType;
+				ReferenceBinding originalEnclosing = originalType.enclosingType();
+				ReferenceBinding substitutedEnclosing = originalEnclosing;
+				if (originalEnclosing != null) {
+					substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing);
+				}
+				if (substitution.isRawSubstitution()) {
+					return originalParameterizedType.environment.createRawType(originalParameterizedType.type, substitutedEnclosing);
+				}				
+				TypeBinding[] originalArguments = originalParameterizedType.arguments;
+				TypeBinding[] substitutedArguments = originalArguments;
+				if (originalArguments != null) {
+					substitutedArguments = substitute(substitution, originalArguments);
+				}
+				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
+					identicalVariables: { // if substituted with original variables, then answer the generic type itself
+						if (substitutedEnclosing != originalEnclosing) break identicalVariables;
+						if (originalParameterizedType.type.isBinaryBinding()) break identicalVariables; // generic binary is never used as is, see 85262
+						TypeVariableBinding[] originalVariables = originalParameterizedType.type.typeVariables();
+						for (int i = 0, length = originalVariables.length; i < length; i++) {
+							if (substitutedArguments[i] != originalVariables[i]) break identicalVariables;
+						}
+						return originalParameterizedType.type;
+					}
+					return originalParameterizedType.environment.createParameterizedType(
+							originalParameterizedType.type, substitutedArguments, substitutedEnclosing);
+				}
+				break;
+				
+			case Binding.ARRAY_TYPE:
+				ArrayBinding originalArrayType = (ArrayBinding) originalType;
+				TypeBinding originalLeafComponentType = originalArrayType.leafComponentType;
+				TypeBinding substitute = substitute(substitution, originalLeafComponentType); // substitute could itself be array type
+				if (substitute != originalLeafComponentType) {
+					return originalArrayType.environment.createArrayType(substitute.leafComponentType(), substitute.dimensions() + originalType.dimensions());
+				}
+				break;
+
+			case Binding.WILDCARD_TYPE:
+		        WildcardBinding wildcard = (WildcardBinding) originalType;
+		        if (wildcard.boundKind != Wildcard.UNBOUND) {
+			        TypeBinding originalBound = wildcard.bound;
+			        TypeBinding substitutedBound = substitute(substitution, originalBound);
+			        TypeBinding[] originalOtherBounds = wildcard.otherBounds;
+			        TypeBinding[] substitutedOtherBounds = substitute(substitution, originalOtherBounds);
+			        if (substitutedBound != originalBound || originalOtherBounds != substitutedOtherBounds) {
+		        		return wildcard.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, substitutedOtherBounds, wildcard.boundKind);
+			        }
+		        }
+				break;
+
+			case Binding.TYPE:
+				if (!originalType.isMemberType()) break;
+				// fall thru in case enclosing is generic
+			case Binding.GENERIC_TYPE:
+				ReferenceBinding originalGenericType = (ReferenceBinding) originalType;
+				originalEnclosing = originalType.enclosingType();
+				substitutedEnclosing = originalEnclosing;
+				if (originalEnclosing != null) {
+					substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing);
+				}
+				if (substitution.isRawSubstitution()) {
+		            return substitution.environment().createRawType(originalGenericType, substitutedEnclosing);
+	            }
+			    // treat as if parameterized with its type variables
+				TypeVariableBinding[] originalVariables = originalGenericType.typeVariables();
+				int length = originalVariables.length;
+				System.arraycopy(originalVariables, 0, originalArguments = new TypeBinding[length], 0, length);
+				substitutedArguments = substitute(substitution, originalArguments);
+				if (substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing) {
+					return substitution.environment().createParameterizedType(
+							originalGenericType, substitutedArguments, substitutedEnclosing);
+				}
+				break;
+		}
+		return originalType;
+	}	
+
+	/**
 	 * Returns an array of types, where original types got substituted given a substitution.
 	 * Only allocate an array if anything is different.
 	 */
 	public static TypeBinding[] substitute(Substitution substitution, TypeBinding[] originalTypes) {
+		if (originalTypes == null) return null;
 	    TypeBinding[] substitutedTypes = originalTypes;
 	    for (int i = 0, length = originalTypes.length; i < length; i++) {
 	        TypeBinding originalType = originalTypes[i];
-	        TypeBinding substitutedParameter = substitution.substitute(originalType);
+	        TypeBinding substitutedParameter = substitute(substitution, originalType);
 	        if (substitutedParameter != originalType) {
 	            if (substitutedTypes == originalTypes) {
 	                System.arraycopy(originalTypes, 0, substitutedTypes = new TypeBinding[length], 0, i);
@@ -93,9 +260,6 @@
 	    return substitutedTypes;
 	}
 
-	public int kind;
-	public Scope parent;
-
 	protected Scope(int kind, Scope parent) {
 		this.kind = kind;
 		this.parent = parent;
@@ -104,72 +268,9 @@
 	/*
 	 * Boxing primitive
 	 */
-	public int boxing(int id) {
-		switch (id) {
-			case T_int :
-				return T_JavaLangInteger;
-			case T_byte :
-				return T_JavaLangByte;
-			case T_short :
-				return T_JavaLangShort;
-			case T_char :
-				return T_JavaLangCharacter;
-			case T_long :
-				return T_JavaLangLong;
-			case T_float :
-				return T_JavaLangFloat;
-			case T_double :
-				return T_JavaLangDouble;
-			case T_boolean :
-				return T_JavaLangBoolean;
-			case T_void :
-				return T_JavaLangVoid;
-		}
-		return id;
-	}
-	/*
-	 * Boxing primitive
-	 */
 	public TypeBinding boxing(TypeBinding type) {
-		TypeBinding boxedType;
-		switch (type.id) {
-			case T_int :
-				boxedType = environment().getType(JAVA_LANG_INTEGER);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_INTEGER, NotFound);				
-			case T_byte :
-				boxedType = environment().getType(JAVA_LANG_BYTE);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_BYTE, NotFound);				
-			case T_short :
-				boxedType = environment().getType(JAVA_LANG_SHORT);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_SHORT, NotFound);				
-			case T_char :
-				boxedType = environment().getType(JAVA_LANG_CHARACTER);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_CHARACTER, NotFound);				
-			case T_long :
-				boxedType = environment().getType(JAVA_LANG_LONG);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_LONG, NotFound);				
-			case T_float :
-				boxedType = environment().getType(JAVA_LANG_FLOAT);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_FLOAT, NotFound);				
-			case T_double :
-				boxedType = environment().getType(JAVA_LANG_DOUBLE);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_DOUBLE, NotFound);				
-			case T_boolean :
-				boxedType = environment().getType(JAVA_LANG_BOOLEAN);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_BOOLEAN, NotFound);				
-			case T_void :
-				boxedType = environment().getType(JAVA_LANG_VOID);
-				if (boxedType != null) return boxedType;
-				return new ProblemReferenceBinding(	JAVA_LANG_VOID, NotFound);				
-		}
+		if (type.isBaseType())
+			return environment().computeBoxingType(type);
 		return type;
 	}	
 
@@ -230,6 +331,19 @@
 				return null; // incompatible
 
 		if (typeVariables != NoTypeVariables) { // generic method
+			TypeBinding[] newArgs = null;
+			for (int i = 0; i < argLength; i++) {
+				TypeBinding param = i < paramLength ? parameters[i] : parameters[paramLength - 1];
+				if (arguments[i].isBaseType() != param.isBaseType()) {
+					if (newArgs == null) {
+						newArgs = new TypeBinding[argLength];
+						System.arraycopy(arguments, 0, newArgs, 0, argLength);
+					}
+					newArgs[i] = environment().computeBoxingType(arguments[i]);
+				}	
+			}
+			if (newArgs != null)
+				arguments = newArgs;
 			method = ParameterizedGenericMethodBinding.computeCompatibleMethod(method, arguments, this, invocationSite);
 			if (method == null) return null; // incompatible
 			if (!method.isValidBinding()) return method; // bound check issue is taking precedence
@@ -269,14 +383,19 @@
 			TypeReference typeRef = typeParameter.type;
 			if (typeRef == null)
 				continue nextVariable;
-			ReferenceBinding superType = this.kind == METHOD_SCOPE
-				? (ReferenceBinding) typeRef.resolveType((BlockScope)this, false/*no bound check*/)
-				: (ReferenceBinding) typeRef.resolveType((ClassScope)this);
+			TypeBinding superType = this.kind == METHOD_SCOPE
+				? typeRef.resolveType((BlockScope)this, false/*no bound check*/)
+				: typeRef.resolveType((ClassScope)this);
 			if (superType == null) {
 				typeVariable.tagBits |= HierarchyHasProblems;
 				noProblems = false;
 				continue nextVariable;
 			}
+			typeRef.resolvedType = superType; // hold onto the problem type
+			if (superType.isArrayType()) {
+				problemReporter().boundCannotBeArray(typeRef, superType);
+				continue nextVariable;
+			}
 			if (superType.isTypeVariable()) {
 				TypeVariableBinding varSuperType = (TypeVariableBinding) superType;
 				if (varSuperType.rank >= typeVariable.rank && varSuperType.declaringElement == typeVariable.declaringElement) {
@@ -286,32 +405,37 @@
 					continue nextVariable;
 				}
 			}
-			if (superType.isFinal())
+			ReferenceBinding superRefType = (ReferenceBinding) superType;
+			if (superRefType.isFinal())
 				problemReporter().finalVariableBound(typeVariable, typeRef);
-			typeRef.resolvedType = superType; // hold onto the problem type
-			if (superType.isClass()) {
-				typeVariable.superclass = superType;
+			if (!superType.isInterface()) {
+				typeVariable.superclass = superRefType;
 			} else {
-				typeVariable.superInterfaces = new ReferenceBinding[] {superType};
+				typeVariable.superInterfaces = new ReferenceBinding[] {superRefType};
 				typeVariable.modifiers |= AccInterface;
 			}
-			typeVariable.firstBound = superType; // first bound used to compute erasure
+			typeVariable.firstBound = superRefType; // first bound used to compute erasure
 
 			TypeReference[] boundRefs = typeParameter.bounds;
 			if (boundRefs != null) {
 				for (int j = 0, k = boundRefs.length; j < k; j++) {
 					typeRef = boundRefs[j];
 					superType = this.kind == METHOD_SCOPE
-						? (ReferenceBinding) typeRef.resolveType((BlockScope)this, false)
-						: (ReferenceBinding) typeRef.resolveType((ClassScope)this);
+						? typeRef.resolveType((BlockScope)this, false)
+						: typeRef.resolveType((ClassScope)this);
 					if (superType == null) {
 						typeVariable.tagBits |= HierarchyHasProblems;
 						noProblems = false;
 						continue nextVariable;
 					}
 					typeRef.resolvedType = superType; // hold onto the problem type
-					if (superType.isClass()) {
-						problemReporter().boundsMustBeAnInterface(typeRef, superType);
+					if (superType.isArrayType()) {
+						problemReporter().boundCannotBeArray(typeRef, superType);
+						continue nextVariable;
+					}
+					superRefType = (ReferenceBinding) superType;
+					if (!superType.isInterface()) {
+						problemReporter().boundMustBeAnInterface(typeRef, superType);
 						typeVariable.tagBits |= HierarchyHasProblems;
 						noProblems = false;
 						continue nextVariable;
@@ -330,9 +454,17 @@
 							continue nextVariable;
 						}
 					}
+					for (int index = typeVariable.superInterfaces.length; --index >= 0;) {
+						if (superType.erasure() == typeVariable.superInterfaces[index].erasure()) {
+							problemReporter().duplicateBounds(typeRef, superType);
+							typeVariable.tagBits |= HierarchyHasProblems;
+							noProblems = false;
+							continue nextVariable;
+						}
+					}
 					int size = typeVariable.superInterfaces.length;
 					System.arraycopy(typeVariable.superInterfaces, 0, typeVariable.superInterfaces = new ReferenceBinding[size + 1], 0, size);
-					typeVariable.superInterfaces[size] = superType;
+					typeVariable.superInterfaces[size] = superRefType;
 				}
 			}
 		}
@@ -340,23 +472,67 @@
 	}
 
 	public TypeBinding convertToRawType(TypeBinding type) {
-		int dimension = type.dimensions();
-		TypeBinding originalType = type.leafComponentType();
-		if (originalType instanceof ReferenceBinding) {
-			ReferenceBinding convertedType = (ReferenceBinding) originalType;
-			ReferenceBinding originalEnclosing = originalType.enclosingType();
-			ReferenceBinding convertedEnclosing = originalEnclosing;
-			if (originalEnclosing != null && convertedType.isStatic() && originalEnclosing.isGenericType()) {
-				convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
+
+		int dimension;
+		TypeBinding originalType;
+		switch(type.kind()) {
+			case Binding.BASE_TYPE :
+			case Binding.TYPE_PARAMETER:
+			case Binding.WILDCARD_TYPE:
+			case Binding.RAW_TYPE:
+				return type;
+			case Binding.ARRAY_TYPE:
+				dimension = type.dimensions();
+				originalType = type.leafComponentType();
+				break;
+			default:
+				dimension = 0;
+				originalType = type;
+		}
+		boolean needToConvert;
+		switch (originalType.kind()) {
+			case Binding.BASE_TYPE :
+				return type;
+			case Binding.GENERIC_TYPE :
+				needToConvert = true;
+				break;
+			case Binding.PARAMETERIZED_TYPE :
+				ParameterizedTypeBinding paramType = (ParameterizedTypeBinding) originalType;
+				needToConvert = paramType.type.isGenericType(); // only recursive call to enclosing type can find parameterizedType with arguments
+				break;
+			default :
+				needToConvert = false;
+				break;
+		}
+		ReferenceBinding originalEnclosing = originalType.enclosingType();
+		TypeBinding convertedType;
+		if (originalEnclosing == null) {
+			convertedType = needToConvert ? environment().createRawType((ReferenceBinding)originalType.erasure(), null) : originalType;
+		} else {
+			ReferenceBinding convertedEnclosing;
+			switch (originalEnclosing.kind()) {
+				case Binding.GENERIC_TYPE :
+				case Binding.PARAMETERIZED_TYPE :
+					if (needToConvert || ((ReferenceBinding)originalType).isStatic()) {
+						convertedEnclosing = (ReferenceBinding) convertToRawType(originalEnclosing);
+					} else {
+						convertedEnclosing = originalEnclosing;
+					}
+					break;
+				default :
+					convertedEnclosing = originalEnclosing;
+					break;
 			}
-			if (originalType.isGenericType()) {
-				convertedType = environment().createRawType(convertedType, convertedEnclosing);
+			if (needToConvert) {
+				convertedType = environment().createRawType((ReferenceBinding) originalType.erasure(), convertedEnclosing);
 			} else if (originalEnclosing != convertedEnclosing) {
-				convertedType = createParameterizedType(convertedType, null, convertedEnclosing);
+				convertedType = createParameterizedType((ReferenceBinding) originalType.erasure(), null, convertedEnclosing);
+			} else {
+				convertedType = originalType;
 			}
-			if (originalType != convertedType) {
-				return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
-			}
+		}
+		if (originalType != convertedType) {
+			return dimension > 0 ? (TypeBinding)createArrayType(convertedType, dimension) : convertedType;
 		}
 		return type;
 	}
@@ -396,45 +572,28 @@
 	}
 	
 	public TypeVariableBinding[] createTypeVariables(TypeParameter[] typeParameters, Binding declaringElement) {
-
-		PackageBinding unitPackage = compilationUnitScope().fPackage;
-		
 		// do not construct type variables if source < 1.5
 		if (typeParameters == null || environment().options.sourceLevel < ClassFileConstants.JDK1_5)
 			return NoTypeVariables;
+
 		TypeVariableBinding[] typeVariableBindings = NoTypeVariables;
-		
+		PackageBinding unitPackage = compilationUnitScope().fPackage;
 		int length = typeParameters.length;
 		typeVariableBindings = new TypeVariableBinding[length];
-		HashtableOfObject knownTypeParameterNames = new HashtableOfObject(length);
 		int count = 0;
-		nextParameter : for (int i = 0; i < length; i++) {
+		for (int i = 0; i < length; i++) {
 			TypeParameter typeParameter = typeParameters[i];
 			TypeVariableBinding parameterBinding = new TypeVariableBinding(typeParameter.name, declaringElement, i);
 			parameterBinding.fPackage = unitPackage;
 			typeParameter.binding = parameterBinding;
-			
-			if (knownTypeParameterNames.containsKey(typeParameter.name)) {
-				TypeVariableBinding previousBinding = (TypeVariableBinding) knownTypeParameterNames.get(typeParameter.name);
-				if (previousBinding != null) {
-					for (int j = 0; j < i; j++) {
-						TypeParameter previousParameter = typeParameters[j];
-						if (previousParameter.binding == previousBinding) {
-							problemReporter().duplicateTypeParameterInType(previousParameter);
-							previousParameter.binding = null;
-							break;
-						}
-					}
-				}
-				knownTypeParameterNames.put(typeParameter.name, null); // ensure that the duplicate parameter is found & removed
-				problemReporter().duplicateTypeParameterInType(typeParameter);
-				typeParameter.binding = null;
-			} else {
-				knownTypeParameterNames.put(typeParameter.name, parameterBinding);
-				// remember that we have seen a field with this name
-				if (parameterBinding != null)
-					typeVariableBindings[count++] = parameterBinding;
+
+			// detect duplicates, but keep each variable to reduce secondary errors with instantiating this generic type (assume number of variables is correct)
+			for (int j = 0; j < count; j++) {
+				TypeVariableBinding knownVar = typeVariableBindings[j];
+				if (CharOperation.equals(knownVar.sourceName, typeParameter.name))
+					problemReporter().duplicateTypeParameterInType(typeParameter);
 			}
+			typeVariableBindings[count++] = parameterBinding;
 //				TODO should offer warnings to inform about hiding declaring, enclosing or member types				
 //				ReferenceBinding type = sourceType;
 //				// check that the member does not conflict with an enclosing type
@@ -453,9 +612,8 @@
 //					}
 //				}
 		}
-		if (count != length) {
+		if (count != length)
 			System.arraycopy(typeVariableBindings, 0, typeVariableBindings = new TypeVariableBinding[count], 0, count);
-		}
 		return typeVariableBindings;
 	}
 
@@ -601,8 +759,13 @@
 						return ParameterizedMethodBinding.instantiateGetClass(receiverType, exactMethod, this);
 			    }
 				// targeting a generic method could find an exact match with variable return type
-				if (exactMethod.typeVariables != NoTypeVariables || invocationSite.genericTypeArguments() != null)
-					exactMethod = computeCompatibleMethod(exactMethod, argumentTypes, invocationSite);
+				if (exactMethod.typeVariables != NoTypeVariables || invocationSite.genericTypeArguments() != null) {
+					MethodBinding compatibleMethod = computeCompatibleMethod(exactMethod, argumentTypes, invocationSite);
+					if (!compatibleMethod.isValidBinding() && exactMethod.typeVariables != NoTypeVariables) {
+						return null; // could be a better generic method match (90423), which will be found by non exact match
+					}
+					exactMethod = compatibleMethod;
+				}
 				return exactMethod;
 			}
 		}
@@ -620,12 +783,28 @@
 		If no visible field is discovered, null is answered.
 	*/
 	public FieldBinding findField(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite, boolean needResolve) {
-		if (receiverType.isBaseType()) return null;
 
 		CompilationUnitScope unitScope = compilationUnitScope();
 		unitScope.recordTypeReference(receiverType);
-		if (receiverType.isArrayType()) {
-			TypeBinding leafType = receiverType.leafComponentType();
+		
+		checkArrayField: {
+			TypeBinding leafType;
+			switch (receiverType.kind()) {
+				case Binding.BASE_TYPE :
+					return null;
+				case Binding.WILDCARD_TYPE :
+				case Binding.TYPE_PARAMETER : // capture
+					TypeBinding receiverErasure = receiverType.erasure();
+					if (!receiverErasure.isArrayType())
+						break checkArrayField;
+					leafType = receiverErasure.leafComponentType();
+					break;
+				case Binding.ARRAY_TYPE :
+					leafType = receiverType.leafComponentType();
+					break;
+				default:
+					break checkArrayField;
+			}
 			if (leafType instanceof ReferenceBinding)
 				if (!((ReferenceBinding) leafType).canBeSeenBy(this))
 					return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ReceiverTypeNotVisible);
@@ -651,7 +830,7 @@
 		int lastPosition = -1;
 		FieldBinding visibleField = null;
 		boolean keepLooking = true;
-		boolean notVisible = false;
+		FieldBinding notVisibleField = null;
 		// we could hold onto the not visible field for extra error reporting
 		while (keepLooking) {
 			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
@@ -678,7 +857,8 @@
 					else
 						return new ProblemFieldBinding(visibleField /* closest match*/, visibleField.declaringClass, fieldName, Ambiguous);
 				} else {
-					notVisible = true;
+					if (notVisibleField == null)
+						notVisibleField = field;
 				}
 			}
 		}
@@ -725,8 +905,8 @@
 
 		if (visibleField != null)
 			return visibleField;
-		if (notVisible)
-			return new ProblemFieldBinding(currentType, fieldName, NotVisible);
+		if (notVisibleField != null)
+			return new ProblemFieldBinding(notVisibleField, currentType, fieldName, NotVisible);
 		return null;
 	}
 
@@ -866,14 +1046,21 @@
 		boolean isCompliant14 = unitScope.environment.options.complianceLevel >= ClassFileConstants.JDK1_4;
 		// superclass lookup
 		ReferenceBinding classHierarchyStart = currentType;
+		boolean mustBePublic = receiverType.isInterface();
 		while (currentType != null) {
 			unitScope.recordTypeReference(currentType);
 			MethodBinding[] currentMethods = currentType.getMethods(selector);
 			int currentLength = currentMethods.length;
 
-			if (isCompliant14 && matchingMethod != null || found.size > 0) {
+			if (isCompliant14 && (mustBePublic || matchingMethod != null || found.size > 0)) {
 				nextMethod: for (int i = 0; i < currentLength; i++) {
 					MethodBinding currentMethod = currentMethods[i];
+					if (mustBePublic && !currentMethod.isPublic()) { // only public methods from Object are visible to interface receiverTypes
+						currentLength--;
+						currentMethods[i] = null;
+						continue nextMethod;
+					}
+
 					// if 1.4 compliant, must filter out redundant protected methods from superclasses
 					// protected method need to be checked only - default access is already dealt with in #canBeSeen implementation
 					// when checking that p.C -> q.B -> p.A cannot see default access members from A through B.
@@ -881,6 +1068,8 @@
 					// BUT we can also ignore any overridden method since we already know the better match (fixes 80028)
 					if (matchingMethod != null) {
 						if (currentMethod.areParametersEqual(matchingMethod)) {
+							if (matchingMethod.hasSubstitutedParameters() && !currentMethod.original().areParametersEqual(matchingMethod.original()))
+								continue nextMethod; // keep inherited substituted methods to detect anonymous errors
 							currentLength--;
 							currentMethods[i] = null; // discard this match
 							continue nextMethod;
@@ -1045,9 +1234,18 @@
 			if (interfaceMethod != null) return interfaceMethod;
 			return new ProblemMethodBinding(candidates[0], candidates[0].selector, candidates[0].parameters, NotVisible);
 		}
-		if (isCompliant14)
-			return mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite);
-		return candidates[0].declaringClass.isClass()
+		if (isCompliant14) {
+			matchingMethod = mostSpecificMethodBinding(candidates, visiblesCount, argumentTypes, invocationSite);
+			if (parameterCompatibilityLevel(matchingMethod, argumentTypes) > COMPATIBLE) {
+				// see if there is a better match in the interfaces
+				MethodBinding interfaceMethod =
+					findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, new ObjectVector());
+				if (interfaceMethod != null) return interfaceMethod;
+			}
+			return matchingMethod;
+		}
+		ReferenceBinding declaringClass = candidates[0].declaringClass;
+		return !declaringClass.isInterface()
 			? mostSpecificClassMethodBinding(candidates, visiblesCount, invocationSite)
 			: mostSpecificInterfaceMethodBinding(candidates, visiblesCount, invocationSite);
 	}
@@ -1066,7 +1264,7 @@
 		}
 
 		ReferenceBinding object = getJavaLangObject();
-		MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes);
+		MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes, null);
 		if (methodBinding != null) {
 			// handle the method clone() specially... cannot be protected or throw exceptions
 			if (argumentTypes == NoParameters) {
@@ -1193,68 +1391,6 @@
 
 		return null;
 	}
-	
-	public static TypeBinding getBaseType(char[] name) {
-		// list should be optimized (with most often used first)
-		int length = name.length;
-		if (length > 2 && length < 8) {
-			switch (name[0]) {
-				case 'i' :
-					if (length == 3 && name[1] == 'n' && name[2] == 't')
-						return IntBinding;
-					break;
-				case 'v' :
-					if (length == 4 && name[1] == 'o' && name[2] == 'i' && name[3] == 'd')
-						return VoidBinding;
-					break;
-				case 'b' :
-					if (length == 7
-						&& name[1] == 'o'
-						&& name[2] == 'o'
-						&& name[3] == 'l'
-						&& name[4] == 'e'
-						&& name[5] == 'a'
-						&& name[6] == 'n')
-						return BooleanBinding;
-					if (length == 4 && name[1] == 'y' && name[2] == 't' && name[3] == 'e')
-						return ByteBinding;
-					break;
-				case 'c' :
-					if (length == 4 && name[1] == 'h' && name[2] == 'a' && name[3] == 'r')
-						return CharBinding;
-					break;
-				case 'd' :
-					if (length == 6
-						&& name[1] == 'o'
-						&& name[2] == 'u'
-						&& name[3] == 'b'
-						&& name[4] == 'l'
-						&& name[5] == 'e')
-						return DoubleBinding;
-					break;
-				case 'f' :
-					if (length == 5
-						&& name[1] == 'l'
-						&& name[2] == 'o'
-						&& name[3] == 'a'
-						&& name[4] == 't')
-						return FloatBinding;
-					break;
-				case 'l' :
-					if (length == 4 && name[1] == 'o' && name[2] == 'n' && name[3] == 'g')
-						return LongBinding;
-					break;
-				case 's' :
-					if (length == 5
-						&& name[1] == 'h'
-						&& name[2] == 'o'
-						&& name[3] == 'r'
-						&& name[4] == 't')
-						return ShortBinding;
-			}
-		}
-		return null;
-	}
 
 	/* API
 	 *	
@@ -1283,7 +1419,8 @@
 			if ((mask & Binding.VARIABLE) != 0) {
 				boolean insideStaticContext = false;
 				boolean insideConstructorCall = false;
-
+				boolean insideTypeAnnotation = false;
+				
 				FieldBinding foundField = null;
 				// can be a problem field which is answered if a valid field is not found
 				ProblemFieldBinding foundInsideProblem = null;
@@ -1298,6 +1435,8 @@
 							MethodScope methodScope = (MethodScope) scope;
 							insideStaticContext |= methodScope.isStatic;
 							insideConstructorCall |= methodScope.isConstructorCall;
+							insideTypeAnnotation = methodScope.insideTypeAnnotation;
+							
 							// Fall through... could duplicate the code below to save a cast - questionable optimization
 						case BLOCK_SCOPE :
 							LocalVariableBinding variableBinding = scope.findVariable(name);
@@ -1317,88 +1456,76 @@
 						case CLASS_SCOPE :
 							ClassScope classScope = (ClassScope) scope;
 							SourceTypeBinding enclosingType = classScope.referenceContext.binding;
-							FieldBinding fieldBinding = classScope.findField(enclosingType, name, invocationSite, needResolve);
-							// Use next line instead if willing to enable protected access accross inner types
-							// FieldBinding fieldBinding = findField(enclosingType, name, invocationSite);
-							
-//							SourceTypeBinding initialType = this.enclosingSourceType();
-//							if ((fieldBinding == null || !fieldBinding.isValidBinding()) && enclosingType.hasMemberTypes()) { // check member enums
-//								ReferenceBinding[] memberTypes = enclosingType.memberTypes();
-//								for (int i = 0, length = memberTypes.length; i < length; i++) {
-//									ReferenceBinding memberType = memberTypes[i];
-//									if (memberType != initialType && memberType.isEnum()) { // do not find one's field through its enclosing members
-//										FieldBinding enumField = ((SourceTypeBinding)memberType).scope.findField(memberType, name, invocationSite, needResolve);
-//										if (enumField != null && (enumField.modifiers & AccEnum) != 0) {
-//											// grant access to enum constants of enclosing members
-//											// TODO (kent) need to revisit to see whether should walk sibling enums and issue an ambiguous match
-//											return enumField;
-//										}
-//									}
-//								}
-//							}
-							if (fieldBinding != null) { // skip it if we did not find anything
-								if (fieldBinding.problemId() == Ambiguous) {
-									if (foundField == null || foundField.problemId() == NotVisible)
-										// supercedes any potential InheritedNameHidesEnclosingName problem
-										return fieldBinding;
-									// 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;
-								if (fieldBinding.isValidBinding()) {
-									if (!fieldBinding.isStatic()) {
-										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);
-										}
+							if (!insideTypeAnnotation) {
+								FieldBinding fieldBinding = classScope.findField(enclosingType, name, invocationSite, needResolve);
+								// Use next line instead if willing to enable protected access accross inner types
+								// FieldBinding fieldBinding = findField(enclosingType, name, invocationSite);
+								
+								if (fieldBinding != null) { // skip it if we did not find anything
+									if (fieldBinding.problemId() == Ambiguous) {
+										if (foundField == null || foundField.problemId() == NotVisible)
+											// supercedes any potential InheritedNameHidesEnclosingName problem
+											return fieldBinding;
+										// 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);
 									}
-									if (enclosingType == fieldBinding.declaringClass || environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
-										// found a valid field in the 'immediate' scope (ie. not inherited)
-										// OR in 1.4 mode (inherited shadows enclosing)
-										if (foundField == null) {
-											if (depth > 0){
-												invocationSite.setDepth(depth);
-												invocationSite.setActualReceiverType(enclosingType);
+	
+									ProblemFieldBinding insideProblem = null;
+									if (fieldBinding.isValidBinding()) {
+										if (!fieldBinding.isStatic()) {
+											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);
 											}
-											// return the fieldBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
-											return insideProblem == null ? fieldBinding : insideProblem;
 										}
-										if (foundField.isValidBinding())
-											// if a valid field was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
-											if (foundField.declaringClass != fieldBinding.declaringClass)
-												// ie. have we found the same field - do not trust field identity yet
-												return new ProblemFieldBinding(
-													foundField, // closest match
-													foundField.declaringClass,
-													name,
-													InheritedNameHidesEnclosingName);
+										if (enclosingType == fieldBinding.declaringClass || environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+											// found a valid field in the 'immediate' scope (ie. not inherited)
+											// OR in 1.4 mode (inherited shadows enclosing)
+											if (foundField == null) {
+												if (depth > 0){
+													invocationSite.setDepth(depth);
+													invocationSite.setActualReceiverType(enclosingType);
+												}
+												// return the fieldBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
+												return insideProblem == null ? fieldBinding : insideProblem;
+											}
+											if (foundField.isValidBinding())
+												// if a valid field was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
+												if (foundField.declaringClass != fieldBinding.declaringClass)
+													// ie. have we found the same field - do not trust field identity yet
+													return new ProblemFieldBinding(
+														foundField, // closest match
+														foundField.declaringClass,
+														name,
+														InheritedNameHidesEnclosingName);
+										}
 									}
-								}
-
-								if (foundField == null || (foundField.problemId() == NotVisible && fieldBinding.problemId() != NotVisible)) {
-									// only remember the fieldBinding if its the first one found or the previous one was not visible & fieldBinding is...
-									foundDepth = depth;
-									foundActualReceiverType = enclosingType;
-									foundInsideProblem = insideProblem;
-									foundField = fieldBinding;
+	
+									if (foundField == null || (foundField.problemId() == NotVisible && fieldBinding.problemId() != NotVisible)) {
+										// only remember the fieldBinding if its the first one found or the previous one was not visible & fieldBinding is...
+										foundDepth = depth;
+										foundActualReceiverType = enclosingType;
+										foundInsideProblem = insideProblem;
+										foundField = fieldBinding;
+									}
 								}
 							}
+							insideTypeAnnotation = false;
 							depth++;
 							insideStaticContext |= enclosingType.isStatic();
 							// 1EX5I8Z - accessing outer fields within a constructor call is permitted
@@ -1425,9 +1552,10 @@
 						return foundField;
 					}
 					problemField = foundField;
+					foundField = null;
 				}
 
-				if (environment().options.complianceLevel >= ClassFileConstants.JDK1_5) {
+				if (environment().options.sourceLevel >= ClassFileConstants.JDK1_5) {
 					// at this point the scope is a compilation unit scope & need to check for imported static fields
 					CompilationUnitScope unitScope = (CompilationUnitScope) scope;
 					ImportBinding[] imports = unitScope.imports;
@@ -1438,9 +1566,15 @@
 							if (importBinding.isStatic() && !importBinding.onDemand) {
 								if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) {
 									if (unitScope.resolveSingleImport(importBinding) != null && importBinding.resolvedImport instanceof FieldBinding) {
-										ImportReference importReference = importBinding.reference;
-										if (importReference != null) importReference.used = true;
-										return importBinding.resolvedImport; // already know its visible
+										ReferenceBinding declaringClass = ((FieldBinding) importBinding.resolvedImport).declaringClass;
+										if (declaringClass.canBeSeenBy(this)) {
+											ImportReference importReference = importBinding.reference;
+											if (importReference != null) importReference.used = true;
+											invocationSite.setActualReceiverType(declaringClass);											
+											return importBinding.resolvedImport;
+										}
+										if (problemField == null)
+											problemField = new ProblemFieldBinding(declaringClass, name, ReceiverTypeNotVisible);
 									}
 								}
 							}
@@ -1455,7 +1589,8 @@
 									FieldBinding temp = findField((ReferenceBinding) resolvedImport, name, invocationSite, needResolve);
 									if (temp != null) {
 										if (!temp.isValidBinding()) {
-											problemField = temp;
+											if (problemField == null)
+												problemField = temp;
 										} else if (temp.isStatic()) {
 											ImportReference importReference = importBinding.reference;
 											if (importReference != null) importReference.used = true;
@@ -1469,7 +1604,10 @@
 								}
 							}
 						}
-						if (foundField != null) return foundField;
+						if (foundField != null) {
+							invocationSite.setActualReceiverType(foundField.declaringClass);							
+							return foundField;
+						}
 					}
 				}
 			}
@@ -1627,6 +1765,7 @@
 
 		boolean insideStaticContext = false;
 		boolean insideConstructorCall = false;
+		boolean insideTypeAnnotation = false;
 		MethodBinding foundMethod = null;
 		MethodBinding foundFuzzyProblem = null;
 		// the weird method lookup case (matches method name in scope, then arg types, then visibility)
@@ -1640,118 +1779,122 @@
 					MethodScope methodScope = (MethodScope) scope;
 					insideStaticContext |= methodScope.isStatic;
 					insideConstructorCall |= methodScope.isConstructorCall;
+					insideTypeAnnotation = methodScope.insideTypeAnnotation;
 					break;
 				case CLASS_SCOPE :
 					ClassScope classScope = (ClassScope) scope;
 					SourceTypeBinding receiverType = classScope.referenceContext.binding;
-					boolean isExactMatch = true;
-					// retrieve an exact visible match (if possible)
-					// compilationUnitScope().recordTypeReference(receiverType);   not needed since receiver is the source type
-					MethodBinding methodBinding =
-						(foundMethod == null)
-							? classScope.findExactMethod(receiverType, selector, argumentTypes, invocationSite)
-							: classScope.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);
+					if (!insideTypeAnnotation) {
+						boolean isExactMatch = true;
+						// retrieve an exact visible match (if possible)
+						// compilationUnitScope().recordTypeReference(receiverType);   not needed since receiver is the source type
+						MethodBinding methodBinding =
+							(foundMethod == null)
+								? classScope.findExactMethod(receiverType, selector, argumentTypes, invocationSite)
+								: classScope.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);
 						}
-						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;
+						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;
 								}
-								// 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);
+								// 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);
 							}
-						}
-
-						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);
+							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);
+								}
 							}
-							foundFuzzyProblem = fuzzyProblem;
-							foundInsideProblem = insideProblem;
-							if (fuzzyProblem == null)
-								foundMethod = methodBinding; // only keep it if no error was found
+	
+							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
+							}
 						}
 					}
+					insideTypeAnnotation = false;
 					depth++;
 					insideStaticContext |= receiverType.isStatic();
 					// 1EX5I8Z - accessing outer fields within a constructor call is permitted
@@ -1774,51 +1917,81 @@
 		if (foundMethod != null)
 			return foundMethod;
 
-		if (insideStaticContext && environment().options.complianceLevel >= ClassFileConstants.JDK1_5) {
+		if (insideStaticContext && environment().options.sourceLevel >= ClassFileConstants.JDK1_5) {
 			// at this point the scope is a compilation unit scope & need to check for imported static methods
 			CompilationUnitScope unitScope = (CompilationUnitScope) scope;
 			ImportBinding[] imports = unitScope.imports;
 			if (imports != null) {
-				// check on demand imports
-				boolean foundInImport = false;
+				int importLevel = -1; // -1 = not found, 0 = on demand match, 1 = single import match
 				for (int i = 0, length = imports.length; i < length; i++) {
 					ImportBinding importBinding = imports[i];
-					if (importBinding.isStatic() && importBinding.onDemand) {
+					if (importBinding.isStatic()) {
 						Binding resolvedImport = importBinding.resolvedImport;
-						if (resolvedImport instanceof ReferenceBinding) {
+						MethodBinding possible = null;
+						if (!importBinding.onDemand && importBinding.isStatic()) {
+							if (resolvedImport instanceof MethodBinding) {
+								MethodBinding staticMethod = (MethodBinding) resolvedImport;
+								if (CharOperation.equals(staticMethod.selector, selector))
+									// answers closest approximation, may not check argumentTypes or visibility
+									possible = findMethod(staticMethod.declaringClass, selector, argumentTypes, invocationSite);
+							} else if (resolvedImport instanceof FieldBinding) {
+								// check to see if there are also methods with the same name
+								FieldBinding staticField = (FieldBinding) resolvedImport;
+								if (CharOperation.equals(staticField.name, selector)) {
+									// must find the importRef's type again since the field can be from an inherited type
+									char[][] importName = importBinding.reference.tokens;
+									TypeBinding referencedType = getType(importName, importName.length - 1);
+									if (referencedType != null)
+										// answers closest approximation, may not check argumentTypes or visibility
+										possible = findMethod((ReferenceBinding) referencedType, selector, argumentTypes, invocationSite);
+								}
+							}
+						} else if (importBinding.onDemand && importLevel < 1 && resolvedImport instanceof ReferenceBinding) {
 							// answers closest approximation, may not check argumentTypes or visibility
-							MethodBinding temp = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes, invocationSite);
-							if (temp != null) {
-								if (!temp.isValidBinding()) {
-									if (foundMethod == null)
-										foundMethod = temp;
-								} else if (temp.isStatic()) {
-									MethodBinding compatibleMethod = computeCompatibleMethod(temp, argumentTypes, invocationSite);
-									if (compatibleMethod != null) {
-										if (compatibleMethod.isValidBinding()) {
-											if (compatibleMethod.canBeSeenBy(unitScope.fPackage)) {
-												ImportReference importReference = importBinding.reference;
-												if (importReference != null) importReference.used = true;
-												if (foundInImport)
-													// Answer error binding -- import on demand conflict; name found in two import on demand types.
-													return new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, Ambiguous);
-												foundMethod = compatibleMethod;
-												foundInImport = true;
-											} else if (foundMethod == null) {
-												foundMethod = new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, NotVisible);
+							possible = findMethod((ReferenceBinding) resolvedImport, selector, argumentTypes, invocationSite);
+						}
+						if (possible != null && possible != foundMethod) {
+							if (!possible.isValidBinding()) {
+								if (foundMethod == null)
+									foundMethod = possible; // answer as error case match
+							} else if (possible.isStatic()) {
+								MethodBinding compatibleMethod = computeCompatibleMethod(possible, argumentTypes, invocationSite);
+								if (compatibleMethod != null) {
+									if (compatibleMethod.isValidBinding()) {
+										if (compatibleMethod.canBeSeenBy(unitScope.fPackage)) {
+											ImportReference importReference = importBinding.reference;
+											if (importReference != null) importReference.used = true;
+											int matchingImportLevel = importBinding.onDemand ? 0 : 1;
+											if (matchingImportLevel == importLevel) {
+												scope = this;
+												while (true) {
+													switch (scope.kind) {
+														case CLASS_SCOPE :
+															return new ProblemMethodBinding(selector, argumentTypes, ((ClassScope) scope).referenceContext.binding, Ambiguous);
+														case COMPILATION_UNIT_SCOPE :
+															return new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, Ambiguous);
+													}
+													scope = scope.parent;
+												}
 											}
+											foundMethod = compatibleMethod;
+											importLevel = matchingImportLevel;
+										} else if (foundMethod == null) {
+											foundMethod = new ProblemMethodBinding(compatibleMethod, selector, compatibleMethod.parameters, NotVisible);
 										}
-									} else if (foundMethod == null) {
-										foundMethod = new ProblemMethodBinding(temp, selector, argumentTypes, NotFound);
 									}
+								} else if (foundMethod == null) {
+									foundMethod = new ProblemMethodBinding(possible, selector, argumentTypes, NotFound);
 								}
 							}
 						}
 					}
 				}
 			}
-			if (foundMethod != null)
+			if (foundMethod != null) {
+				invocationSite.setActualReceiverType(foundMethod.declaringClass);
 				return foundMethod;
+			}
 		}
 		return new ProblemMethodBinding(selector, argumentTypes, NotFound);
 	}
@@ -1944,12 +2117,14 @@
 
 	public MethodBinding getMethod(TypeBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
 		try {
-			if (receiverType.isBaseType())
-				return new ProblemMethodBinding(selector, argumentTypes, NotFound);
-
+			switch (receiverType.kind()) {
+				case Binding.BASE_TYPE :
+					return new ProblemMethodBinding(selector, argumentTypes, NotFound);
+				case Binding.ARRAY_TYPE :
+					compilationUnitScope().recordTypeReference(receiverType);
+					return findMethodForArray((ArrayBinding) receiverType, selector, argumentTypes, invocationSite);
+			}
 			compilationUnitScope().recordTypeReference(receiverType);
-			if (receiverType.isArrayType())
-				return findMethodForArray((ArrayBinding) receiverType, selector, argumentTypes, invocationSite);
 
 			ReferenceBinding currentType = (ReferenceBinding) receiverType;
 			if (!currentType.canBeSeenBy(this))
@@ -1975,6 +2150,13 @@
 				if (!methodBinding.canBeSeenBy(currentType, invocationSite, this))
 					return new ProblemMethodBinding( methodBinding, selector, methodBinding.parameters, NotVisible);
 			}
+			// special treatment for Object.getClass() in 1.5 mode (substitute parameterized return type)
+			if (receiverType.id != T_JavaLangObject
+				&& argumentTypes == NoParameters
+			    && CharOperation.equals(selector, GETCLASS)
+			    && methodBinding.returnType.isParameterizedType()/*1.5*/) {
+					return ParameterizedMethodBinding.instantiateGetClass(receiverType, methodBinding, this);
+		    }			
 			return methodBinding;
 		} catch (AbortCompilation e) {
 			e.updateContext(invocationSite, referenceCompilationUnit().compilationResult);
@@ -2137,6 +2319,7 @@
 		Scope scope = this;
 		ReferenceBinding foundType = null;
 		boolean insideStaticContext = false;
+		boolean insideTypeAnnotation = false;
 		if ((mask & Binding.TYPE) == 0) {
 			Scope next = scope;
 			while ((next = scope.parent) != null)
@@ -2152,6 +2335,7 @@
 							if (typeVariable != null)	return typeVariable;
 						}
 						insideStaticContext |= methodScope.isStatic;
+						insideTypeAnnotation = methodScope.insideTypeAnnotation;
 					case BLOCK_SCOPE :
 						ReferenceBinding localType = ((BlockScope) scope).findLocalType(name); // looks in this scope only
 						if (localType != null) {
@@ -2169,6 +2353,7 @@
 								return typeVariable;
 							if (CharOperation.equals(name, sourceType.sourceName))
 								return sourceType;
+							insideStaticContext |= (sourceType.modifiers & AccStatic) != 0; // not isStatic()
 							break;
 						}
 						// type variables take precedence over member types
@@ -2179,32 +2364,37 @@
 							return typeVariable;
 						}
 						insideStaticContext |= (sourceType.modifiers & AccStatic) != 0; // not isStatic()
-						// 6.5.5.1 - member types have precedence over top-level type in same unit
-						ReferenceBinding memberType = findMemberType(name, sourceType);
-						if (memberType != null) { // skip it if we did not find anything
-							if (memberType.problemId() == Ambiguous) {
-								if (foundType == null || foundType.problemId() == NotVisible)
-									// supercedes any potential InheritedNameHidesEnclosingName problem
-									return memberType;
-								// make the user qualify the type, likely wants the first inherited type
-								return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
-							}
-							if (memberType.isValidBinding()) {
-								if (sourceType == memberType.enclosingType()
-										|| environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
-									// found a valid type in the 'immediate' scope (ie. not inherited)
-									// OR in 1.4 mode (inherited shadows enclosing)
-									if (foundType == null)
-										return memberType; 
-									// if a valid type was found, complain when another is found in an 'immediate' enclosing type (ie. not inherited)
-									if (foundType.isValidBinding() && foundType != memberType)
-										return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
+						if (!insideTypeAnnotation) {
+							// 6.5.5.1 - member types have precedence over top-level type in same unit
+							ReferenceBinding memberType = findMemberType(name, sourceType);
+							if (memberType != null) { // skip it if we did not find anything
+								if (memberType.problemId() == Ambiguous) {
+									if (foundType == null || foundType.problemId() == NotVisible)
+										// supercedes any potential InheritedNameHidesEnclosingName problem
+										return memberType;
+									// make the user qualify the type, likely wants the first inherited type
+									return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
 								}
+								if (memberType.isValidBinding()) {
+									if (sourceType == memberType.enclosingType()
+											|| environment().options.complianceLevel >= ClassFileConstants.JDK1_4) {
+										if (insideStaticContext && !memberType.isStatic() && sourceType.isGenericType())
+											return new ProblemReferenceBinding(name, NonStaticReferenceInStaticContext);
+										// found a valid type in the 'immediate' scope (ie. not inherited)
+										// OR in 1.4 mode (inherited shadows enclosing)
+										if (foundType == null)
+											return memberType; 
+										// if a valid type was found, complain when another is found in an 'immediate' enclosing type (ie. not inherited)
+										if (foundType.isValidBinding() && foundType != memberType)
+											return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
+									}
+								}
+								if (foundType == null || (foundType.problemId() == NotVisible && memberType.problemId() != NotVisible))
+									// only remember the memberType if its the first one found or the previous one was not visible & memberType is...
+									foundType = memberType;
 							}
-							if (foundType == null || (foundType.problemId() == NotVisible && memberType.problemId() != NotVisible))
-								// only remember the memberType if its the first one found or the previous one was not visible & memberType is...
-								foundType = memberType;
 						}
+						insideTypeAnnotation = false;
 						if (CharOperation.equals(sourceType.sourceName, name)) {
 							if (foundType != null && foundType != sourceType && foundType.problemId() != NotVisible)
 								return new ProblemReferenceBinding(name, InheritedNameHidesEnclosingName);
@@ -2238,16 +2428,17 @@
 						return typeImport.resolvedImport; // already know its visible
 					}
 				} else {
-					// walk all the imports since resolvedSingeTypeImports is not yet initialized
+					// walk all the imports since resolvedSingleTypeImports is not yet initialized
 					for (int i = 0, length = imports.length; i < length; i++) {
 						ImportBinding typeImport = imports[i];
 						if (!typeImport.onDemand) {
 							if (CharOperation.equals(typeImport.compoundName[typeImport.compoundName.length - 1], name)) {
-								if (unitScope.resolveSingleImport(typeImport) != null) {
+								Binding resolvedImport = unitScope.resolveSingleImport(typeImport);
+								if (resolvedImport != null && resolvedImport instanceof TypeBinding) {
 									ImportReference importReference = typeImport.reference;
 									if (importReference != null)
 										importReference.used = true;
-									return typeImport.resolvedImport; // already know its visible
+									return resolvedImport; // already know its visible
 								}
 							}
 						}
@@ -2377,13 +2568,15 @@
 	}
 	
 	// 5.1.10
-	public TypeBinding[] greaterLowerBound(TypeBinding[] types) {
+	public static TypeBinding[] greaterLowerBound(TypeBinding[] types) {
 		if (types == null) return null;
 		int length = types.length;
+		if (length == 0) return null;
 		TypeBinding[] result = types;
 		int removed = 0;
 		for (int i = 0; i < length; i++) {
 			TypeBinding iType = result[i];
+			if (iType == null) continue;
 			for (int j = 0; j < length; j++) {
 				if (i == j) continue;
 				TypeBinding jType = result[j];
@@ -2398,6 +2591,7 @@
 			}
 		}
 		if (removed == 0) return result;
+		if (length == removed) return null;
 		TypeBinding[] trimmedResult = new TypeBinding[length - removed];
 		for (int i = 0, index = 0; i < length; i++) {
 			TypeBinding iType = result[i];
@@ -2407,6 +2601,53 @@
 		}
 		return trimmedResult;
 	}
+	
+	// 5.1.10
+	public static ReferenceBinding[] greaterLowerBound(ReferenceBinding[] types) {
+		if (types == null) return null;
+		int length = types.length;
+		if (length == 0) return null;
+		ReferenceBinding[] result = types;
+		int removed = 0;
+		for (int i = 0; i < length; i++) {
+			ReferenceBinding iType = result[i];
+			if (iType == null) continue;
+			for (int j = 0; j < length; j++) {
+				if (i == j) continue;
+				ReferenceBinding jType = result[j];
+				if (jType == null) continue;
+				if (iType.isCompatibleWith(jType)) { // if Vi <: Vj, Vj is removed
+					if (result == types) { // defensive copy
+						System.arraycopy(result, 0, result = new ReferenceBinding[length], 0, length);
+					}
+					result[j] = null;
+					removed ++;
+				}
+			}
+		}
+		if (removed == 0) return result;
+		if (length == removed) return null;
+		ReferenceBinding[] trimmedResult = new ReferenceBinding[length - removed];
+		for (int i = 0, index = 0; i < length; i++) {
+			ReferenceBinding iType = result[i];
+			if (iType != null) {
+				trimmedResult[index++] = iType;
+			}
+		}
+		return trimmedResult;
+	}	
+	/**
+	 * Returns the immediately enclosing switchCase statement (carried by closest blockScope),
+	 */
+	public CaseStatement innermostSwitchCase() {
+		Scope scope = this;
+		do {
+			if (scope instanceof BlockScope)
+				return ((BlockScope) scope).enclosingCase;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}
 
 	public boolean isBoxingCompatibleWith(TypeBinding left, TypeBinding right) {
 		return left.isBaseType() != right.isBaseType() && environment().isBoxingCompatibleWith(left, right);
@@ -2478,6 +2719,24 @@
 		return false;
 	}
 
+	/** 
+	 * Returns true if the scope or one of its parent is associated to a given caseStatement, denoting
+	 * being part of a given switch case statement.
+	 */
+	public boolean isInsideCase(CaseStatement caseStatement) {
+		Scope scope = this;
+		do {
+			switch (scope.kind) {
+				case Scope.BLOCK_SCOPE :
+					if (((BlockScope) scope).enclosingCase == caseStatement) {
+						return true;
+					}
+			}
+			scope = scope.parent;
+		} while (scope != null);
+		return false;
+	}
+	
 	public boolean isInsideDeprecatedCode(){
 		switch(this.kind){
 			case Scope.BLOCK_SCOPE :
@@ -2505,30 +2764,31 @@
 		}
 		return false;
 	}
-	private TypeBinding leastContainingInvocation(TypeBinding mec, List invocations) {
+	private TypeBinding leastContainingInvocation(TypeBinding mec, Set invocations, List lubStack) {
+		if (invocations == null) return mec; // no alternate invocation
 		int length = invocations.size();
-		if (length == 0) return mec;
-		if (length == 1) return (TypeBinding) invocations.get(0);
+		Iterator iter = invocations.iterator();
+		if (length == 1) return (TypeBinding) iter.next();
 		int argLength = mec.typeVariables().length;
 		if (argLength == 0) return mec; // should be caught by no invocation check
 
 		// infer proper parameterized type from invocations
 		TypeBinding[] bestArguments = new TypeBinding[argLength];
-		for (int i = 0; i < length; i++) {
-			TypeBinding invocation = (TypeBinding)invocations.get(i);
+		while (iter.hasNext()) {
+			TypeBinding invocation = (TypeBinding)iter.next();
 			TypeVariableBinding[] invocationVariables = invocation.typeVariables();
 			if (invocation.isGenericType()) {
-				for (int j = 0; j < argLength; j++) {
-					TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[j], invocationVariables[j], (ReferenceBinding) mec, j);
+				for (int i = 0; i < argLength; i++) {
+					TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[i], invocationVariables[i], (ReferenceBinding) mec, i, lubStack);
 					if (bestArgument == null) return null;
-					bestArguments[j] = bestArgument;
+					bestArguments[i] = bestArgument;
 				}
 			} else if (invocation.isParameterizedType()) {
 				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding)invocation;
-				for (int j = 0; j < argLength; j++) {
-					TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[j], parameterizedType.arguments[j], (ReferenceBinding) mec, j);
+				for (int i = 0; i < argLength; i++) {
+					TypeBinding bestArgument = leastContainingTypeArgument(bestArguments[i], parameterizedType.arguments[i], (ReferenceBinding) mec, i, lubStack);
 					if (bestArgument == null) return null;
-					bestArguments[j] = bestArgument;
+					bestArguments[i] = bestArgument;
 				}
 			} else if (invocation.isRawType()) {
 				return invocation; // raw type is taking precedence
@@ -2538,83 +2798,144 @@
 	}
 	
 	// JLS 15.12.2
-	private TypeBinding leastContainingTypeArgument(TypeBinding u, TypeBinding v, ReferenceBinding genericType, int rank) {
+	private TypeBinding leastContainingTypeArgument(TypeBinding u, TypeBinding v, ReferenceBinding genericType, int rank, List lubStack) {
 		if (u == null) return v;
 		if (u == v) return u;
 		if (v.isWildcard()) {
 			WildcardBinding wildV = (WildcardBinding) v;
 			if (u.isWildcard()) {
 				WildcardBinding wildU = (WildcardBinding) u;
-				switch (wildU.kind) {
+				switch (wildU.boundKind) {
 					// ? extends U
 					case Wildcard.EXTENDS :
-						switch(wildV.kind) {
+						switch(wildV.boundKind) {
 							// ? extends U, ? extends V
 							case Wildcard.EXTENDS :  
-								TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound,wildV.bound});
+								TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound,wildV.bound}, lubStack);
 								if (lub == null) return null;
-								return environment().createWildcard(genericType, rank, lub, Wildcard.EXTENDS);	
+								// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+								if (lub == IntBinding) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+								return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);	
 							// ? extends U, ? SUPER V
 							case Wildcard.SUPER : 
 								if (wildU.bound == wildV.bound) return wildU.bound;
-								return environment().createWildcard(genericType, rank, null, Wildcard.UNBOUND);
+								return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
 						}
 						break;
 						// ? super U
 					case Wildcard.SUPER : 
 						// ? super U, ? super V
-						if (wildU.kind == Wildcard.SUPER) {
+						if (wildU.boundKind == Wildcard.SUPER) {
 							TypeBinding[] glb = greaterLowerBound(new TypeBinding[]{wildU.bound,wildV.bound});
 							if (glb == null) return null;
-							return environment().createWildcard(genericType, rank, glb[0], Wildcard.SUPER);	// TODO (philippe) need to capture entire bounds
+							return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER);	// TODO (philippe) need to capture entire bounds
 						}
 				}				
 			} else {
-				switch (wildV.kind) {
+				switch (wildV.boundKind) {
 					// U, ? extends V
 					case Wildcard.EXTENDS :
-						TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,wildV.bound});
+						TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,wildV.bound}, lubStack);
 						if (lub == null) return null;
-						return environment().createWildcard(genericType, rank, lub, Wildcard.EXTENDS);	
+						// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+						if (lub == IntBinding) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+						return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);	
 					// U, ? super V
 					case Wildcard.SUPER :
 						TypeBinding[] glb = greaterLowerBound(new TypeBinding[]{u,wildV.bound});
 						if (glb == null) return null;
-						return environment().createWildcard(genericType, rank, glb[0], Wildcard.SUPER);	// TODO (philippe) need to capture entire bounds
+						return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER);	// TODO (philippe) need to capture entire bounds
 					case Wildcard.UNBOUND :
 				}
 			}
 		} else if (u.isWildcard()) {
 			WildcardBinding wildU = (WildcardBinding) u;
-			switch (wildU.kind) {
+			switch (wildU.boundKind) {
 				// U, ? extends V
 				case Wildcard.EXTENDS :
-					TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound, v});
+					TypeBinding lub = lowerUpperBound(new TypeBinding[]{wildU.bound, v}, lubStack);
 					if (lub == null) return null;
-					return environment().createWildcard(genericType, rank, lub, Wildcard.EXTENDS);	
+					// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+					if (lub == IntBinding) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+					return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);	
 				// U, ? super V
 				case Wildcard.SUPER :
 					TypeBinding[] glb = greaterLowerBound(new TypeBinding[]{wildU.bound, v});
 					if (glb == null) return null;
-					return environment().createWildcard(genericType, rank, glb[0], Wildcard.SUPER); // TODO (philippe) need to capture entire bounds		
+					return environment().createWildcard(genericType, rank, glb[0], null /*no extra bound*/, Wildcard.SUPER); // TODO (philippe) need to capture entire bounds		
 				case Wildcard.UNBOUND :
 			}
 		}
-		TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,v});
+		TypeBinding lub = lowerUpperBound(new TypeBinding[]{u,v}, lubStack);
 		if (lub == null) return null;
-		return environment().createWildcard(genericType, rank, lub, Wildcard.EXTENDS);
+		// int is returned to denote cycle detected in lub computation - stop recursion by answering unbound wildcard
+		if (lub == IntBinding) return environment().createWildcard(genericType, rank, null, null /*no extra bound*/, Wildcard.UNBOUND);
+		return environment().createWildcard(genericType, rank, lub, null /*no extra bound*/, Wildcard.EXTENDS);
 	}
 
 	// 15.12.2
 	public TypeBinding lowerUpperBound(TypeBinding[] types) {
+		return lowerUpperBound(types, new ArrayList(1));
+	}
+	
+	// 15.12.2
+	private TypeBinding lowerUpperBound(TypeBinding[] types, List lubStack) {
 		
-		if (types.length == 1) {
+		int typeLength = types.length;
+		if (typeLength == 1) {
 			TypeBinding type = types[0];
 			return type == null ? VoidBinding : type;
 		}
-		ArrayList invocations = new ArrayList(1);
-		TypeBinding mec = minimalErasedCandidate(types, invocations);
-		return leastContainingInvocation(mec, invocations);
+		// cycle detection
+		int stackLength = lubStack.size();
+		nextLubCheck: for (int i = 0; i < stackLength; i++) {
+			TypeBinding[] lubTypes = (TypeBinding[])lubStack.get(i);
+			int lubTypeLength = lubTypes.length;
+			if (lubTypeLength < typeLength) continue nextLubCheck;
+			nextTypeCheck:	for (int j = 0; j < typeLength; j++) {
+				TypeBinding type = types[j];
+				for (int k = 0; k < lubTypeLength; k++) {
+					if (lubTypes[k] == type) continue nextTypeCheck; // type found, jump to next one
+				}
+				continue nextLubCheck; // type not found in current lubTypes
+			}
+			// all types are included in some lub, cycle detected - stop recursion by answering special value (int)
+			return IntBinding;
+		}
+
+		lubStack.add(types);
+		Map invocations = new HashMap(1);
+		TypeBinding[] mecs = minimalErasedCandidates(types, invocations);
+		if (mecs == null) return null;
+		int length = mecs.length;
+		if (length == 0) return VoidBinding;
+		int count = 0;
+		TypeBinding firstBound = null;
+		for (int i = 0; i < length; i++) {
+			TypeBinding mec = mecs[i];
+			if (mec == null) continue;
+			mec = leastContainingInvocation(mec, (Set)invocations.get(mec), lubStack);
+			if (mec == null) return null;
+			if (!mec.isInterface()) firstBound = mec;
+			mecs[count++] = mec; // recompact them to the front
+
+		}
+		switch (count) {
+			case 0 : return VoidBinding;
+			case 1 : return mecs[0];
+			case 2 : 
+				if (mecs[1].id == T_JavaLangObject) return mecs[0];
+				if (mecs[0].id == T_JavaLangObject) return mecs[1];
+		}
+		TypeBinding[] otherBounds = new TypeBinding[count - 1];
+		int rank = 0;
+		for (int i = 0; i < count; i++) {
+			TypeBinding mec = mecs[i];
+			if (mec.isInterface()) {
+				otherBounds[rank++] = (ReferenceBinding)mec;
+			}
+		}
+		return environment().createWildcard(null, 0, firstBound, otherBounds, Wildcard.EXTENDS);
 	}
 	
 	public final MethodScope methodScope() {
@@ -2628,13 +2949,14 @@
 	}
 
 	/**
-	 * Returns the most specific type compatible with all given types.
-	 * (i.e. most specific common super type)
-	 * If no types is given, will return VoidBinding. If not compatible 
-	 * reference type is found, returns null.
+	 * Returns the most specific set of types compatible with all given types.
+	 * (i.e. most specific common super types)
+	 * If no types is given, will return an empty array. If not compatible 
+	 * reference type is found, returns null. In other cases, will return an array 
+	 * of minimal erased types, where some nulls may appear (and must simply be
+	 * ignored).
 	 */
-	private TypeBinding minimalErasedCandidate(TypeBinding[] types, List invocations) {
-		Map allInvocations = new HashMap(2);
+	private TypeBinding[] minimalErasedCandidates(TypeBinding[] types, Map allInvocations) {
 		int length = types.length;
 		int indexOfFirst = -1, actualLength = 0;
 		for (int i = 0; i < length; i++) {
@@ -2645,8 +2967,8 @@
 			actualLength ++;
 		}
 		switch (actualLength) {
-			case 0: return VoidBinding;
-			case 1: return types[indexOfFirst];
+			case 0: return NoTypes;
+			case 1: return types;
 		}
 
 		// record all supertypes of type
@@ -2663,7 +2985,7 @@
 				someInvocations.add(firstType);
 				allInvocations.put(firstType.erasure(), someInvocations);
 			}
-			superTypes = new TypeBinding[] {
+			superTypes = new TypeBinding[] { // inject well-known array supertypes
 					firstType.erasure(), 
 					getJavaIoSerializable(),
 					getJavaLangCloneable(),
@@ -2671,35 +2993,33 @@
 			};
 		} else {
 			ArrayList typesToVisit = new ArrayList(5);
-			if (firstType.erasure() != firstType) {
-				ArrayList someInvocations = new ArrayList(1);
+			TypeBinding firstErasure = firstType.erasure();
+			if (firstErasure != firstType) {
+				Set someInvocations = new HashSet(1);
 				someInvocations.add(firstType);
-				allInvocations.put(firstType.erasure(), someInvocations);
-			}			
-			typesToVisit.add(firstType.erasure());
+				allInvocations.put(firstErasure, someInvocations);
+			}
+			typesToVisit.add(firstErasure);
+			int max = 1;
+			if (firstErasure.isArrayType()) {
+				typesToVisit.add(getJavaIoSerializable());
+				typesToVisit.add(getJavaLangCloneable());
+				typesToVisit.add(getJavaLangObject());
+				max += 3;
+			}
 			ReferenceBinding currentType = (ReferenceBinding)firstType;
-			for (int i = 0, max = 1; i < max; i++) {
-				currentType = (ReferenceBinding) typesToVisit.get(i);
-				TypeBinding itsSuperclass = currentType.superclass();
-				if (itsSuperclass != null) {
-					TypeBinding itsSuperclassErasure = itsSuperclass.erasure();
-					if (!typesToVisit.contains(itsSuperclassErasure)) {
-						if (itsSuperclassErasure != itsSuperclass) {
-							ArrayList someInvocations = new ArrayList(1);
-							someInvocations.add(itsSuperclass);
-							allInvocations.put(itsSuperclassErasure, someInvocations);
-						}
-						typesToVisit.add(itsSuperclassErasure);
-						max++;
-					}
-				}
+			for (int i = 0; i < max; i++) {
+				TypeBinding typeToVisit = (TypeBinding) typesToVisit.get(i);
+				if (typeToVisit.isArrayType()) continue;
+				currentType = (ReferenceBinding) typeToVisit;
+				// inject super interfaces prior to superclass
 				ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
 				for (int j = 0, count = itsInterfaces.length; j < count; j++) {
 					TypeBinding itsInterface = itsInterfaces[j];
 					TypeBinding itsInterfaceErasure = itsInterface.erasure();
 					if (!typesToVisit.contains(itsInterfaceErasure)) {
 						if (itsInterfaceErasure != itsInterface) {
-							ArrayList someInvocations = new ArrayList(1);
+							Set someInvocations = new HashSet(1);
 							someInvocations.add(itsInterface);
 							allInvocations.put(itsInterfaceErasure, someInvocations);
 						}						
@@ -2707,17 +3027,30 @@
 						max++;
 					}
 				}
+				TypeBinding itsSuperclass = currentType.superclass();
+				if (itsSuperclass != null) {
+					TypeBinding itsSuperclassErasure = itsSuperclass.erasure();
+					if (!typesToVisit.contains(itsSuperclassErasure)) {
+						if (itsSuperclassErasure != itsSuperclass) {
+							Set someInvocations = new HashSet(1);
+							someInvocations.add(itsSuperclass);
+							allInvocations.put(itsSuperclassErasure, someInvocations);
+						}
+						typesToVisit.add(itsSuperclassErasure);
+						max++;
+					}
+				}
 			}
 			superLength = typesToVisit.size();
 			superTypes = new TypeBinding[superLength];
 			typesToVisit.toArray(superTypes);
 		}
+		// intersecting first type supertypes with other types' ones, nullifying non matching supertypes
 		int remaining = superLength;
 		nextOtherType: for (int i = indexOfFirst+1; i < length; i++) {
 			TypeBinding otherType = types[i];
-			if (otherType == null)
-				continue nextOtherType;
-			else if (otherType.isArrayType()) {
+			if (otherType == null) continue nextOtherType;
+			if (otherType.isArrayType()) {
 				nextSuperType: for (int j = 0; j < superLength; j++) {
 					TypeBinding superType = superTypes[j];
 					if (superType == null || superType == otherType) continue nextSuperType;
@@ -2737,31 +3070,46 @@
 			nextSuperType: for (int j = 0; j < superLength; j++) {
 				TypeBinding superType = superTypes[j];
 				if (superType == null) continue nextSuperType;
-				if (otherRefType.erasure().isCompatibleWith(superType)) {
-					TypeBinding match = otherRefType.findSuperTypeErasingTo((ReferenceBinding)superType);
-						if (match != null && match.erasure() != match) { // match can be null: interface.findSuperTypeErasingTo(Object)
-							ArrayList someInvocations = (ArrayList) allInvocations.get(superType);
-							if (someInvocations == null) someInvocations = new ArrayList(1);
-							someInvocations.add(match);
-							allInvocations.put(superType, someInvocations);
-						}						
-					break nextSuperType;
+				TypeBinding match;
+				if (superType == otherType || superType.id == T_JavaLangObject && otherType.isInterface()) {
+					match = superType;
 				} else {
-					superTypes[j] = null;
-					if (--remaining == 0) return null;
+					if (superType.isArrayType()) {
+						match = null;
+					} else {
+						match = otherRefType.findSuperTypeErasingTo((ReferenceBinding)superType);
+					}
+					if (match == null) { // incompatible super type
+						superTypes[j] = null;
+						if (--remaining == 0) return null;
+						continue nextSuperType;
+					}
 				}
+				// record invocation
+				Set someInvocations = (Set) allInvocations.get(superType);
+				if (someInvocations == null) someInvocations = new HashSet(1);
+				someInvocations.add(match);
+				allInvocations.put(superType, someInvocations);
 			}				
 		}
-		// per construction, first non-null supertype is most specific common supertype
-		for (int i = 0; i < superLength; i++) {
-			TypeBinding superType = superTypes[i];
-			if (superType != null) {
-				List matchingInvocations = (List)allInvocations.get(superType);
-				if (matchingInvocations != null) invocations.addAll(matchingInvocations);
-				return superType;
+		// eliminate non minimal super types
+		if (remaining > 1) {
+			nextType: for (int i = 0; i < superLength; i++) {
+				ReferenceBinding superType = (ReferenceBinding)superTypes[i];
+				if (superType == null) continue nextType;
+				nextOtherType: for (int j = 0; j < superLength; j++) {
+					if (i == j) continue nextOtherType;
+					ReferenceBinding otherType = (ReferenceBinding)superTypes[j];
+					if (otherType == null) continue nextOtherType;
+					if (otherType.id == T_JavaLangObject && superType.isInterface()) continue nextOtherType;
+					if (superType.findSuperTypeErasingTo(otherType) != null) {
+						superTypes[j] = null; // discard non minimal supertype
+						remaining--;
+					}
+				}
 			}
 		}
-		return null;
+		return superTypes;
 	}
 	
 	// Internal use only
@@ -2847,23 +3195,62 @@
 		for (int i = 0; i < visibleSize; i++)
 			compatibilityLevels[i] = parameterCompatibilityLevel(visible[i], argumentTypes);
 
-		for (int level = 0; level <= 2; level++) {
+		for (int level = 0; level <= VARARGS_COMPATIBLE; level++) {
 			nextVisible : for (int i = 0; i < visibleSize; i++) {
 				if (compatibilityLevels[i] != level) continue nextVisible; // skip this method for now
 				MethodBinding method = visible[i];
+				TypeBinding[] params = method.tiebreakMethod().parameters;
 				for (int j = 0; j < visibleSize; j++) {
 					if (i == j || compatibilityLevels[j] != level) continue;
+					MethodBinding method2 = visible[j];
 					// tiebreak generic methods using variant where type params are substituted by their erasures
-					if (!visible[j].tiebreakMethod().areParametersCompatibleWith(method.tiebreakMethod().parameters)) {
-						if (method.isVarargs() && visible[j].isVarargs()) {
-							int paramLength = method.parameters.length;
-							if (paramLength == visible[j].parameters.length && paramLength == argumentTypes.length + 1) {
-								TypeBinding elementsType = ((ArrayBinding) visible[j].parameters[paramLength - 1]).elementsType();
-								if (method.parameters[paramLength - 1].isCompatibleWith(elementsType))
-									continue; // special case to choose between 2 varargs methods when the last arg is missing
-							}
+					if (!method2.tiebreakMethod().areParametersCompatibleWith(params)) {
+						if (method.isVarargs() && method2.isVarargs()) {
+							// check the non-vararg parameters
+							int paramLength = params.length;
+							TypeBinding[] params2 = method2.tiebreakMethod().parameters;
+							if (paramLength != params2.length)
+								continue nextVisible;
+							for (int p = paramLength - 2; p >= 0; p--)
+								if (params[p] != params2[p] && !params[p].isCompatibleWith(params2[p]))
+									continue nextVisible;
+
+							TypeBinding elementsType = ((ArrayBinding) params2[paramLength - 1]).elementsType();
+							if (params[paramLength - 1].isCompatibleWith(elementsType))
+								continue; // special case to choose between 2 varargs methods when the last arg is missing or its Object[]
 						}
 						continue nextVisible;
+					} else if (method.hasSubstitutedParameters() && method.isAbstract() == method2.isAbstract()) { // must both be abstract or concrete, not one of each
+						if (method.areParametersEqual(method2)) {
+							// its possible with 2 abstract methods that one does not inherit from the other
+							// need to find their methods from the receiver type
+							MethodBinding original = method.original();
+							MethodBinding original2 = method2.original();
+							if (original.areParameterErasuresEqual(original2)) continue;
+							ReferenceBinding receiverType = (ReferenceBinding) ((MessageSend) invocationSite).actualReceiverType;
+							if (receiverType != method.declaringClass) {
+								ReferenceBinding superType = ((ReferenceBinding) receiverType.erasure()).findSuperTypeErasingTo(original.declaringClass);
+								MethodBinding[] superMethods = superType.getMethods(original.selector);
+								for (int m = 0, l = superMethods.length; m < l; m++) {
+									if (superMethods[m].original() == original) {
+										original = superMethods[m];
+										break;
+									}
+								}
+							}
+							if (receiverType != method2.declaringClass) {
+								ReferenceBinding superType = ((ReferenceBinding) receiverType.erasure()).findSuperTypeErasingTo(original2.declaringClass);
+								MethodBinding[] superMethods = superType.getMethods(original2.selector);
+								for (int m = 0, l = superMethods.length; m < l; m++) {
+									if (superMethods[m].original() == original2) {
+										original2 = superMethods[m];
+										break;
+									}
+								}
+							}
+							if (!original.areParametersEqual(original2))
+								continue nextVisible; // cannot be substituted from 2 different type variables
+						}
 					}
 				}
 				compilationUnitScope().recordTypeReferences(method.thrownExceptions);
@@ -2899,30 +3286,43 @@
 		TypeBinding[] parameters = method.parameters;
 		int paramLength = parameters.length;
 		int argLength = arguments.length;
-		int lastIndex = argLength;
+
+		LookupEnvironment env = environment();
+		if (env.options.sourceLevel < ClassFileConstants.JDK1_5) {
+			if (paramLength != argLength)
+				return NOT_COMPATIBLE;
+			for (int i = 0; i < argLength; i++) {
+				TypeBinding param = parameters[i];
+				TypeBinding arg = arguments[i];
+				if (arg != param && !arg.isCompatibleWith(param))
+					return NOT_COMPATIBLE;
+			}
+			return COMPATIBLE;
+		}
+
 		int level = COMPATIBLE; // no autoboxing or varargs support needed
+		int lastIndex = argLength;
 		if (method.isVarargs()) {
 			lastIndex = paramLength - 1;
 			if (paramLength == argLength) { // accept X or X[] but not X[][]
 				TypeBinding param = parameters[lastIndex]; // is an ArrayBinding by definition
 				TypeBinding arg = arguments[lastIndex];
-				if (param != arg && !arg.isCompatibleWith(param)) {
-					if (isBoxingCompatibleWith(arg, param)) {
-						level = AUTOBOX_COMPATIBLE; // autoboxing support needed
-					} else {
-						// expect X[], called with X
+				if (param != arg) {
+					level = parameterCompatibilityLevel(arg, param, env);
+					if (level == NOT_COMPATIBLE) {
+						// expect X[], is it called with X
 						param = ((ArrayBinding) param).elementsType();
-						if (!arg.isCompatibleWith(param) && !isBoxingCompatibleWith(arg, param))
+						if (parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE)
 							return NOT_COMPATIBLE;
 						level = VARARGS_COMPATIBLE; // varargs support needed
 					}
 				}
 			} else {
-				if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
+				if (paramLength < argLength) { // all remaining argument types must be compatible with the elementsType of varArgType
 					TypeBinding param = ((ArrayBinding) parameters[lastIndex]).elementsType();
 					for (int i = lastIndex; i < argLength; i++) {
 						TypeBinding arg = arguments[i];
-						if (param != arg && !arg.isCompatibleWith(param) && !isBoxingCompatibleWith(arg, param))
+						if (param != arg && parameterCompatibilityLevel(arg, param, env) == NOT_COMPATIBLE)
 							return NOT_COMPATIBLE;
 					}
 				}  else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
@@ -2935,15 +3335,29 @@
 		for (int i = 0; i < lastIndex; i++) {
 			TypeBinding param = parameters[i];
 			TypeBinding arg = arguments[i];
-			if (arg != param && !arg.isCompatibleWith(param)) {
-				if (!isBoxingCompatibleWith(arg, param))
+			if (arg != param) {
+				int newLevel = parameterCompatibilityLevel(arg, param, env);
+				if (newLevel == NOT_COMPATIBLE)
 					return NOT_COMPATIBLE;
-				level = AUTOBOX_COMPATIBLE; // autoboxing support needed
+				if (newLevel > level)
+					level = newLevel;
 			}
 		}
 		return level;
 	}
 
+	private int parameterCompatibilityLevel(TypeBinding arg, TypeBinding param, LookupEnvironment env) {
+		// only called if env.options.sourceLevel >= ClassFileConstants.JDK1_5
+		if (arg.isCompatibleWith(param))
+			return COMPATIBLE;
+		if (arg.isBaseType() != param.isBaseType()) {
+			TypeBinding convertedType = env.computeBoxingType(arg);
+			if (convertedType == param || convertedType.isCompatibleWith(param))
+				return AUTOBOX_COMPATIBLE;
+		}
+		return NOT_COMPATIBLE;
+	}
+
 	public abstract ProblemReporter problemReporter();
 
 	public final CompilationUnitDeclaration referenceCompilationUnit() {
@@ -2956,69 +3370,4 @@
 	int startIndex() {
 		return 0;
 	}
-	
-	/**
-	 * Returns the immediately enclosing switchCase statement (carried by closest blockScope),
-	 */
-	public CaseStatement switchCase() {
-		Scope scope = this;
-		do {
-			if (scope instanceof BlockScope)
-				return ((BlockScope) scope).switchCase;
-			scope = scope.parent;
-		} while (scope != null);
-		return null;
-	}
-	/*
-	 * Unboxing primitive
-	 */
-	public int unboxing(int id) {
-		switch (id) {
-			case T_JavaLangInteger :
-				return T_int;
-			case T_JavaLangByte :
-				return T_byte;
-			case T_JavaLangShort :
-				return T_short;
-			case T_JavaLangCharacter :
-				return T_char;
-			case T_JavaLangLong :
-				return T_long;
-			case T_JavaLangFloat :
-				return T_float;
-			case T_JavaLangDouble :
-				return T_double;
-			case T_JavaLangBoolean :
-				return T_boolean;
-			case T_JavaLangVoid :
-				return T_void;
-		}
-		return id;
-	}
-	/*
-	 * Unboxing primitive
-	 */
-	public TypeBinding unboxing(TypeBinding type) {
-		switch (type.id) {
-			case T_JavaLangInteger :
-				return IntBinding;
-			case T_JavaLangByte :
-				return ByteBinding;
-			case T_JavaLangShort :
-				return ShortBinding;		
-			case T_JavaLangCharacter :
-				return CharBinding;				
-			case T_JavaLangLong :
-				return LongBinding;
-			case T_JavaLangFloat :
-				return FloatBinding;
-			case T_JavaLangDouble :
-				return DoubleBinding;
-			case T_JavaLangBoolean :
-				return BooleanBinding;
-			case T_JavaLangVoid :
-				return VoidBinding;
-		}
-		return type;
-	}		
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java
index b4293a0..d293f20 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index 6c1b032..7f164d3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -79,14 +79,13 @@
 	if ((tagBits & KnowsDefaultAbstractMethods) != 0) return;
 
 	tagBits |= KnowsDefaultAbstractMethods;
-
 	if (isClass() && isAbstract()) {
-		if (fPackage.environment.options.targetJDK >= ClassFileConstants.JDK1_2) return; // no longer added for post 1.2 targets
+		if (fPackage.environment.options.targetJDK >= ClassFileConstants.JDK1_2)
+			return; // no longer added for post 1.2 targets
 
 		ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
 		int lastPosition = 0;
 		interfacesToVisit[lastPosition] = superInterfaces();
-
 		for (int i = 0; i <= lastPosition; i++) {
 			ReferenceBinding[] interfaces = interfacesToVisit[i];
 			for (int j = 0, length = interfaces.length; j < length; j++) {
@@ -113,14 +112,11 @@
 /* Add a new synthetic field for <actualOuterLocalVariable>.
 *	Answer the new field or the existing field if one already existed.
 */
-
 public FieldBinding addSyntheticFieldForInnerclass(LocalVariableBinding actualOuterLocalVariable) {
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[FIELD_EMUL] == null) {
+	if (synthetics[FIELD_EMUL] == null)
 		synthetics[FIELD_EMUL] = new HashMap(5);
-	}
 	
 	FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get(actualOuterLocalVariable);
 	if (synthField == null) {
@@ -160,15 +156,11 @@
 /* Add a new synthetic field for <enclosingType>.
 *	Answer the new field or the existing field if one already existed.
 */
-
 public FieldBinding addSyntheticFieldForInnerclass(ReferenceBinding enclosingType) {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[FIELD_EMUL] == null) {
+	if (synthetics[FIELD_EMUL] == null)
 		synthetics[FIELD_EMUL] = new HashMap(5);
-	}
 
 	FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get(enclosingType);
 	if (synthField == null) {
@@ -184,31 +176,38 @@
 		synthetics[FIELD_EMUL].put(enclosingType, synthField);
 	}
 	// ensure there is not already such a field defined by the user
-	FieldBinding existingField;
-	if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
-		TypeDeclaration typeDecl = scope.referenceContext;
-		for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
-			FieldDeclaration fieldDecl = typeDecl.fields[i];
-			if (fieldDecl.binding == existingField) {
-				scope.problemReporter().duplicateFieldInType(this, fieldDecl);
-				break;
+	boolean needRecheck;
+	do {
+		needRecheck = false;
+		FieldBinding existingField;
+		if ((existingField = this.getField(synthField.name, true /*resolve*/)) != null) {
+			TypeDeclaration typeDecl = scope.referenceContext;
+			for (int i = 0, max = typeDecl.fields.length; i < max; i++) {
+				FieldDeclaration fieldDecl = typeDecl.fields[i];
+				if (fieldDecl.binding == existingField) {
+					if (this.scope.environment().options.complianceLevel >= ClassFileConstants.JDK1_5) {
+						synthField.name = CharOperation.concat(
+							synthField.name,
+							"$".toCharArray()); //$NON-NLS-1$
+						needRecheck = true;
+					} else {
+						scope.problemReporter().duplicateFieldInType(this, fieldDecl);
+					}
+					break;
+				}
 			}
 		}
-	}		
+	} while (needRecheck);
 	return synthField;
 }
 /* Add a new synthetic field for a class literal access.
 *	Answer the new field or the existing field if one already existed.
 */
-
 public FieldBinding addSyntheticFieldForClassLiteral(TypeBinding targetType, BlockScope blockScope) {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[CLASS_LITERAL_EMUL] == null) {
+	if (synthetics[CLASS_LITERAL_EMUL] == null)
 		synthetics[CLASS_LITERAL_EMUL] = new HashMap(5);
-	}
 
 	// use a different table than FIELDS, given there might be a collision between emulation of X.this$0 and X.class.
 	FieldBinding synthField = (FieldBinding) synthetics[CLASS_LITERAL_EMUL].get(targetType);
@@ -238,18 +237,14 @@
 	}		
 	return synthField;
 }
-
 /* Add a new synthetic field for the emulation of the assert statement.
 *	Answer the new field or the existing field if one already existed.
 */
 public FieldBinding addSyntheticFieldForAssert(BlockScope blockScope) {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[FIELD_EMUL] == null) {
+	if (synthetics[FIELD_EMUL] == null)
 		synthetics[FIELD_EMUL] = new HashMap(5);
-	}
 
 	FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get("assertionEmulation"); //$NON-NLS-1$
 	if (synthField == null) {
@@ -285,18 +280,14 @@
 	} while (needRecheck);
 	return synthField;
 }
-
 /* Add a new synthetic field for recording all enum constant values
 *	Answer the new field or the existing field if one already existed.
 */
 public FieldBinding addSyntheticFieldForEnumValues() {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[FIELD_EMUL] == null) {
+	if (synthetics[FIELD_EMUL] == null)
 		synthetics[FIELD_EMUL] = new HashMap(5);
-	}
 
 	FieldBinding synthField = (FieldBinding) synthetics[FIELD_EMUL].get("enumConstantValues"); //$NON-NLS-1$
 	if (synthField == null) {
@@ -332,19 +323,14 @@
 	} while (needRecheck);
 	return synthField;
 }
-
 /* Add a new synthetic access method for read/write access to <targetField>.
 	Answer the new method or the existing method if one already existed.
 */
-
 public SyntheticMethodBinding addSyntheticMethod(FieldBinding targetField, boolean isReadAccess) {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[METHOD_EMUL] == null) {
+	if (synthetics[METHOD_EMUL] == null)
 		synthetics[METHOD_EMUL] = new HashMap(5);
-	}
 
 	SyntheticMethodBinding accessMethod = null;
 	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(targetField);
@@ -363,15 +349,11 @@
 /* Add a new synthetic method the enum type. Selector can either be 'values' or 'valueOf'.
  * char[] constants from TypeConstants must be used: TypeConstants.VALUES/VALUEOF
 */
-
 public SyntheticMethodBinding addSyntheticEnumMethod(char[] selector) {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[METHOD_EMUL] == null) {
+	if (synthetics[METHOD_EMUL] == null)
 		synthetics[METHOD_EMUL] = new HashMap(5);
-	}
 
 	SyntheticMethodBinding accessMethod = null;
 	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(selector);
@@ -391,15 +373,11 @@
  * Must distinguish access method used for super access from others (need to use invokespecial bytecode)
 	Answer the new method or the existing method if one already existed.
 */
-
 public SyntheticMethodBinding addSyntheticMethod(MethodBinding targetMethod, boolean isSuperAccess) {
-
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
-	if (synthetics[METHOD_EMUL] == null) {
+	if (synthetics[METHOD_EMUL] == null)
 		synthetics[METHOD_EMUL] = new HashMap(5);
-	}
 
 	SyntheticMethodBinding accessMethod = null;
 	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(targetMethod);
@@ -418,15 +396,15 @@
 /* 
  * Record the fact that bridge methods need to be generated to override certain inherited methods
  */
-public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge, MethodBinding localTargetMethod) {
-	if (!isClass()) return null; // only classes get bridge methods
-	if (inheritedMethodToBridge.returnType.erasure() == localTargetMethod.returnType.erasure()
-		&& inheritedMethodToBridge.areParameterErasuresEqual(localTargetMethod)) {
+public SyntheticMethodBinding addSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge, MethodBinding targetMethod) {
+	if (isInterface()) return null; // only classes & enums get bridge methods
+	// targetMethod may be inherited
+	if (inheritedMethodToBridge.returnType.erasure() == targetMethod.returnType.erasure()
+		&& inheritedMethodToBridge.areParameterErasuresEqual(targetMethod)) {
 			return null; // do not need bridge method
 	}
-	if (synthetics == null) {
+	if (synthetics == null)
 		synthetics = new HashMap[4];
-	}
 	if (synthetics[METHOD_EMUL] == null) {
 		synthetics[METHOD_EMUL] = new HashMap(5);
 	} else {
@@ -448,83 +426,132 @@
 	SyntheticMethodBinding accessMethod = null;
 	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(inheritedMethodToBridge);
 	if (accessors == null) {
-		accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, localTargetMethod);
+		accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this);
 		synthetics[METHOD_EMUL].put(inheritedMethodToBridge, accessors = new SyntheticMethodBinding[2]);
 		accessors[1] = accessMethod;		
 	} else {
 		if ((accessMethod = accessors[1]) == null) {
-			accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, localTargetMethod);
+			accessMethod = new SyntheticMethodBinding(inheritedMethodToBridge, targetMethod, this);
 			accessors[1] = accessMethod;
 		}
 	}
 	return accessMethod;
 }
-
 /**
  * Collect the substitutes into a map for certain type variables inside the receiver type
- * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
+ * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
  */
-public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
-	if (otherType instanceof ReferenceBinding) {
-		TypeVariableBinding[] variables = this.typeVariables;
-		if (variables == NoTypeVariables) return;
-		// generic type is acting as parameterized type with its own parameters as arguments
-		
-		// allow List<T> to match with LinkedList<String>
-		ReferenceBinding equivalent = this;
-        ReferenceBinding otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeErasingTo(this);
-        if (otherEquivalent == null) {
-        	// allow LinkedList<String> to match List<T> (downcast scenario)
-	    	equivalent = this.findSuperTypeErasingTo((ReferenceBinding)otherType.erasure());
-        	if (equivalent == null) return;
-        	otherEquivalent = (ReferenceBinding)otherType;
-        }
-        TypeBinding[] elements;
-        switch (equivalent.kind()) {
-        	case Binding.GENERIC_TYPE :
-        		elements = equivalent.typeVariables();
-        		break;
-        	case Binding.PARAMETERIZED_TYPE :
-        		elements = ((ParameterizedTypeBinding)equivalent).arguments;
-        		break;
-        	default :
-        		return;
-        }
-        TypeBinding[] otherElements;
-        switch (otherEquivalent.kind()) {
-        	case Binding.GENERIC_TYPE :
-        		otherElements = otherEquivalent.typeVariables();
-        		break;
-        	case Binding.PARAMETERIZED_TYPE :
-        		otherElements = ((ParameterizedTypeBinding)otherEquivalent).arguments;
-        		break;
-        	case Binding.RAW_TYPE :
-        		substitutes.clear(); // clear all variables to indicate raw generic method in the end
-        		return;
-        	default :
-        		return;
-        }
-        for (int i = 0, length = elements.length; i < length; i++) {
-            elements[i].collectSubstitutes(otherElements[i], substitutes);
-        }
+public void collectSubstitutes(Scope currentScope, TypeBinding otherType, Map substitutes, int constraint) {
+	
+	if (otherType == NullBinding) return;
+	if (!(otherType instanceof ReferenceBinding)) return;
+	TypeVariableBinding[] variables = this.typeVariables;
+	if (variables == NoTypeVariables) return;
+	// generic type is acting as parameterized type with its own parameters as arguments
+	
+	ReferenceBinding equivalent, otherEquivalent;
+	switch (constraint) {
+		case CONSTRAINT_EQUAL :
+		case CONSTRAINT_EXTENDS :
+			equivalent = this;
+	        otherEquivalent = ((ReferenceBinding)otherType).findSuperTypeErasingTo(this);
+	        if (otherEquivalent == null) return;
+	        break;
+		case CONSTRAINT_SUPER :
+        default:
+	        equivalent = this.findSuperTypeErasingTo((ReferenceBinding)(otherType.erasure()));
+	        if (equivalent == null) return;
+	        otherEquivalent = (ReferenceBinding) otherType;
+	        break;
+	}
+    TypeBinding[] elements;
+    switch (equivalent.kind()) {
+    	case Binding.GENERIC_TYPE :
+    		elements = equivalent.typeVariables();
+    		break;
+    	case Binding.PARAMETERIZED_TYPE :
+    		elements = ((ParameterizedTypeBinding)equivalent).arguments;
+    		break;
+    	case Binding.RAW_TYPE :
+    		substitutes.clear(); // clear all variables to indicate raw generic method in the end
+    	default :
+    		return;
+    }
+    TypeBinding[] otherElements;
+    switch (otherEquivalent.kind()) {
+    	case Binding.GENERIC_TYPE :
+    		otherElements = otherEquivalent.typeVariables();
+    		break;
+    	case Binding.PARAMETERIZED_TYPE :
+    		otherElements = ((ParameterizedTypeBinding)otherEquivalent).arguments;
+    		break;
+    	case Binding.RAW_TYPE :
+    		substitutes.clear(); // clear all variables to indicate raw generic method in the end
+    		return;
+    	default :
+    		return;
+    }
+    for (int i = 0, length = elements.length; i < length; i++) {
+    	TypeBinding otherElement = otherElements[i];
+        elements[i].collectSubstitutes(scope, otherElements[i], substitutes, otherElement.isWildcard() ? constraint : CONSTRAINT_EQUAL);
     }
 }
-	
 public int kind() {
 	if (this.typeVariables != NoTypeVariables) return Binding.GENERIC_TYPE;
 	return Binding.TYPE;
-}	
-
+}
+public char[] computeUniqueKey(boolean withAccessFlags) {
+	char[] uniqueKey = super.computeUniqueKey(withAccessFlags);
+	if (uniqueKey.length == 2) return uniqueKey; // problem type's unique key is "L;"
+	int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
+	int end = CharOperation.lastIndexOf('.', this.fileName);
+	if (end != -1) {
+		char[] mainTypeName = CharOperation.subarray(this.fileName, start, end);
+		start = CharOperation.lastIndexOf('/', uniqueKey) + 1;
+		if (start == 0)
+			start = 1; // start after L
+		end = CharOperation.indexOf('$', uniqueKey, start);
+		if (end == -1)
+			end = CharOperation.indexOf('<', uniqueKey, start);
+		if (end == -1)
+			end = CharOperation.indexOf(';', uniqueKey, start);
+		char[] topLevelType = CharOperation.subarray(uniqueKey, start, end);
+		if (!CharOperation.equals(topLevelType, mainTypeName)) {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append(uniqueKey, 0, start);
+			buffer.append(mainTypeName);
+			buffer.append('~');
+			buffer.append(topLevelType);
+			buffer.append(uniqueKey, end, uniqueKey.length - end);
+			int length = buffer.length();
+			uniqueKey = new char[length];
+			buffer.getChars(0, length, uniqueKey, 0);
+			return uniqueKey;
+		}
+	}
+	return uniqueKey;
+}
 void faultInTypesForFieldsAndMethods() {
+	// check @Deprecated annotation
+	if ((this.getAnnotationTagBits() & AnnotationDeprecated) != 0) {
+		this.modifiers |= AccDeprecated;
+	} else if ((this.modifiers & AccDeprecated) != 0 && scope != null && scope.environment().options.sourceLevel >= JDK1_5) {
+		scope.problemReporter().missingDeprecatedAnnotationForType(scope.referenceContext);
+	}
+	ReferenceBinding enclosingType = this.enclosingType();
+	if (enclosingType != null && enclosingType.isViewedAsDeprecated() && !this.isDeprecated())
+		modifiers |= AccDeprecatedImplicitly;
 	fields();
 	methods();
 
 	for (int i = 0, length = memberTypes.length; i < length; i++)
 		((SourceTypeBinding) memberTypes[i]).faultInTypesForFieldsAndMethods();
 }
-
 // NOTE: the type of each field of a source type is resolved when needed
 public FieldBinding[] fields() {
+	if ((tagBits & AreFieldsComplete) != 0)
+		return fields;	
+
 	int failed = 0;
 	try {
 		for (int i = 0, length = fields.length; i < length; i++) {
@@ -539,7 +566,7 @@
 			int newSize = fields.length - failed;
 			if (newSize == 0)
 				return fields = NoFields;
-	
+
 			FieldBinding[] newFields = new FieldBinding[newSize];
 			for (int i = 0, j = 0, length = fields.length; i < length; i++)
 				if (fields[i] != null)
@@ -547,31 +574,15 @@
 			fields = newFields;
 		}
 	}
+	tagBits |= AreFieldsComplete;
 	return fields;
 }
 /**
  * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#genericTypeSignature()
  */
 public char[] genericTypeSignature() {
-    if (this.genericReferenceTypeSignature == null) {
-        if (this.typeVariables == NoTypeVariables) {
-	        this.genericReferenceTypeSignature = this.signature();
-        } else {
-		    char[] typeSig = this.signature();
-		    StringBuffer sig = new StringBuffer(10);
-		    for (int i = 0; i < typeSig.length-1; i++) { // copy all but trailing semicolon
-		    	sig.append(typeSig[i]);
-		    }
-		    sig.append('<');
-		    for (int i = 0, length = this.typeVariables.length; i < length; i++) {
-		        sig.append(this.typeVariables[i].genericTypeSignature());
-		    }
-		    sig.append(">;"); //$NON-NLS-1$
-			int sigLength = sig.length();
-			this.genericReferenceTypeSignature = new char[sigLength];
-			sig.getChars(0, sigLength, this.genericReferenceTypeSignature, 0);		    
-	    }
-    }
+    if (this.genericReferenceTypeSignature == null)
+    	this.genericReferenceTypeSignature = computeGenericTypeSignature(this.typeVariables);
     return this.genericReferenceTypeSignature;
 }
 /**
@@ -583,29 +594,25 @@
 	if (this.typeVariables != NoTypeVariables) {
 	    sig = new StringBuffer(10);
 	    sig.append('<');
-	    for (int i = 0, length = this.typeVariables.length; i < length; i++) {
+	    for (int i = 0, length = this.typeVariables.length; i < length; i++)
 	        sig.append(this.typeVariables[i].genericSignature());
-	    }
 	    sig.append('>');
 	} else {
 	    // could still need a signature if any of supertypes is parameterized
 	    noSignature: if (this.superclass == null || !this.superclass.isParameterizedType()) {
-		    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
-		        if (this.superInterfaces[i].isParameterizedType()) break noSignature;
-		    }        
+		    for (int i = 0, length = this.superInterfaces.length; i < length; i++)
+		        if (this.superInterfaces[i].isParameterizedType())
+					break noSignature;
 	        return null;
 	    }
 	    sig = new StringBuffer(10);
 	}
-	if (this.superclass != null) {
+	if (this.superclass != null)
 		sig.append(this.superclass.genericTypeSignature());
-	} else {
-		// interface scenario only (as Object cannot be generic) - 65953
+	else // interface scenario only (as Object cannot be generic) - 65953
 		sig.append(scope.getJavaLangObject().genericTypeSignature());
-	}
-    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
+    for (int i = 0, length = this.superInterfaces.length; i < length; i++)
         sig.append(this.superInterfaces[i].genericTypeSignature());
-    }
 	return sig.toString().toCharArray();
 }
 /**
@@ -616,7 +623,13 @@
 public long getAnnotationTagBits() {
 	if ((this.tagBits & AnnotationResolved) == 0) {
 		TypeDeclaration typeDecl = this.scope.referenceContext;
-		ASTNode.resolveAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this);
+		boolean old = typeDecl.staticInitializerScope.insideTypeAnnotation;
+		try {
+			typeDecl.staticInitializerScope.insideTypeAnnotation = true;
+			ASTNode.resolveAnnotations(typeDecl.staticInitializerScope, typeDecl.annotations, this);
+		} finally {
+			typeDecl.staticInitializerScope.insideTypeAnnotation = old;
+		}
 	}
 	return this.tagBits;
 }
@@ -635,11 +648,10 @@
 	return result;
 }
 // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
-
 public MethodBinding getExactConstructor(TypeBinding[] argumentTypes) {
 	int argCount = argumentTypes.length;
 
-	if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
+	if ((tagBits & AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
 		nextMethod : for (int m = methods.length; --m >= 0;) {
 			MethodBinding method = methods[m];
 			if (method.selector == TypeConstants.INIT && method.parameters.length == argCount) {
@@ -667,14 +679,13 @@
 }
 // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
 // searches up the hierarchy as long as no potential (but not exact) match was found.
-
 public MethodBinding getExactMethod(char[] selector, TypeBinding[] argumentTypes, CompilationUnitScope refScope) {
 	// sender from refScope calls recordTypeReference(this)
 	int argCount = argumentTypes.length;
 	int selectorLength = selector.length;
 	boolean foundNothing = true;
 
-	if ((modifiers & AccUnresolved) == 0) { // have resolved all arg types & return type of the methods
+	if ((tagBits & AreMethodsComplete) != 0) { // have resolved all arg types & return type of the methods
 		nextMethod : for (int m = methods.length; --m >= 0;) {
 			MethodBinding method = methods[m];
 			if (method.selector.length == selectorLength && CharOperation.equals(method.selector, selector)) {
@@ -718,7 +729,6 @@
 	}
 	return null;
 }
-
 // NOTE: the type of a field of a source type is resolved when needed
 public FieldBinding getField(char[] fieldName, boolean needResolve) {
 	// always resolve anyway on source types
@@ -748,11 +758,10 @@
 	}
 	return null;
 }
-
 // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
 public MethodBinding[] getMethods(char[] selector) {
 	int selectorLength = selector.length;
-	boolean methodsAreResolved = (modifiers & AccUnresolved) == 0; // have resolved all arg types & return type of the methods
+	boolean methodsAreResolved = (tagBits & AreMethodsComplete) != 0; // have resolved all arg types & return type of the methods
 	java.util.ArrayList matchingMethods = null;
 	for (int i = 0, length = methods.length; i < length; i++) {
 		MethodBinding method = methods[i];
@@ -766,7 +775,8 @@
 			matchingMethods.add(method);
 		}
 	}
-	if (matchingMethods == null) return NoMethods;
+	if (matchingMethods == null)
+		return NoMethods;
 
 	MethodBinding[] result = new MethodBinding[matchingMethods.size()];
 	matchingMethods.toArray(result);
@@ -789,17 +799,37 @@
 /* Answer the synthetic field for <actualOuterLocalVariable>
 *	or null if one does not exist.
 */
-
 public FieldBinding getSyntheticField(LocalVariableBinding actualOuterLocalVariable) {
-	
 	if (synthetics == null || synthetics[FIELD_EMUL] == null) return null;
 	return (FieldBinding) synthetics[FIELD_EMUL].get(actualOuterLocalVariable);
 }
+/* Answer the synthetic field for <targetEnclosingType>
+*	or null if one does not exist.
+*/
+public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
+
+	if (synthetics == null || synthetics[FIELD_EMUL] == null) return null;
+	FieldBinding field = (FieldBinding) synthetics[FIELD_EMUL].get(targetEnclosingType);
+	if (field != null) return field;
+
+	// type compatibility : to handle cases such as
+	// class T { class M{}}
+	// class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
+	if (!onlyExactMatch){
+		Iterator accessFields = synthetics[FIELD_EMUL].values().iterator();
+		while (accessFields.hasNext()) {
+			field = (FieldBinding) accessFields.next();
+			if (CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, field.name)
+				&& ((ReferenceBinding) field.type).findSuperTypeErasingTo(targetEnclosingType) != null)
+					return field;
+		}
+	}
+	return null;
+}
 /* 
  * Answer the bridge method associated for an  inherited methods or null if one does not exist
  */
 public SyntheticMethodBinding getSyntheticBridgeMethod(MethodBinding inheritedMethodToBridge) {
-    
 	if (synthetics == null) return null;
 	if (synthetics[METHOD_EMUL] == null) return null;
 	SyntheticMethodBinding[] accessors = (SyntheticMethodBinding[]) synthetics[METHOD_EMUL].get(inheritedMethodToBridge);
@@ -813,55 +843,49 @@
 public boolean isEquivalentTo(TypeBinding otherType) {
 
 	if (this == otherType) return true;
-    if (otherType == null) return false;
-    switch(otherType.kind()) {
+	if (otherType == null) return false;
+	switch(otherType.kind()) {
 
-    	case Binding.WILDCARD_TYPE :
+		case Binding.WILDCARD_TYPE :
 			return ((WildcardBinding) otherType).boundCheck(this);
-    	
-    	case Binding.PARAMETERIZED_TYPE :
-	        if ((otherType.tagBits & HasDirectWildcard) == 0 && (!this.isMemberType() || !otherType.isMemberType())) 
-	        	return false; // should have been identical
-	        ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
-	        if (this != otherParamType.type) 
-	            return false;
-            if (!isStatic()) { // static member types do not compare their enclosing
-		        ReferenceBinding enclosing = enclosingType();
-		        if (enclosing != null && !enclosing.isEquivalentTo(otherParamType.enclosingType()))
-		            return false;
-            }
-	        int length = this.typeVariables == null ? 0 : this.typeVariables.length;
-	        TypeBinding[] otherArguments = otherParamType.arguments;
-	        int otherLength = otherArguments == null ? 0 : otherArguments.length;
-	        if (otherLength != length) 
-	            return false;
-	        for (int i = 0; i < length; i++) {
-	        	if (!this.typeVariables[i].isTypeArgumentContainedBy(otherArguments[i]))
+
+		case Binding.PARAMETERIZED_TYPE :
+			if ((otherType.tagBits & HasDirectWildcard) == 0 && (!this.isMemberType() || !otherType.isMemberType())) 
+				return false; // should have been identical
+			ParameterizedTypeBinding otherParamType = (ParameterizedTypeBinding) otherType;
+			if (this != otherParamType.type) 
+				return false;
+			if (!isStatic()) { // static member types do not compare their enclosing
+				ReferenceBinding enclosing = enclosingType();
+				if (enclosing != null && !enclosing.isEquivalentTo(otherParamType.enclosingType()))
 					return false;
-	        }
-	        return true;
-    	
-    	case Binding.RAW_TYPE :
+			}
+			int length = this.typeVariables == null ? 0 : this.typeVariables.length;
+			TypeBinding[] otherArguments = otherParamType.arguments;
+			int otherLength = otherArguments == null ? 0 : otherArguments.length;
+			if (otherLength != length) 
+				return false;
+			for (int i = 0; i < length; i++)
+				if (!this.typeVariables[i].isTypeArgumentContainedBy(otherArguments[i]))
+					return false;
+			return true;
+
+		case Binding.RAW_TYPE :
 	        return otherType.erasure() == this;
-    }
+	}
 	return false;
 }
-	
 public boolean isGenericType() {
     return this.typeVariables != NoTypeVariables;
 }
-
 public ReferenceBinding[] memberTypes() {
 	return this.memberTypes;
 }
 public FieldBinding getUpdatedFieldBinding(FieldBinding targetField, ReferenceBinding newDeclaringClass) {
-
-	if (this.synthetics == null) {
+	if (this.synthetics == null)
 		this.synthetics = new HashMap[4];
-	}
-	if (this.synthetics[RECEIVER_TYPE_EMUL] == null) {
+	if (this.synthetics[RECEIVER_TYPE_EMUL] == null)
 		this.synthetics[RECEIVER_TYPE_EMUL] = new HashMap(5);
-	}
 
 	Hashtable fieldMap = (Hashtable) this.synthetics[RECEIVER_TYPE_EMUL].get(targetField);
 	if (fieldMap == null) {
@@ -875,16 +899,11 @@
 	}
 	return updatedField;
 }
-
 public MethodBinding getUpdatedMethodBinding(MethodBinding targetMethod, ReferenceBinding newDeclaringClass) {
-
-	if (this.synthetics == null) {
+	if (this.synthetics == null)
 		this.synthetics = new HashMap[4];
-	}
-	if (this.synthetics[RECEIVER_TYPE_EMUL] == null) {
+	if (this.synthetics[RECEIVER_TYPE_EMUL] == null)
 		this.synthetics[RECEIVER_TYPE_EMUL] = new HashMap(5);
-	}
-
 
 	Hashtable methodMap = (Hashtable) synthetics[RECEIVER_TYPE_EMUL].get(targetMethod);
 	if (methodMap == null) {
@@ -903,7 +922,7 @@
 }
 // NOTE: the return type, arg & exception types of each method of a source type are resolved when needed
 public MethodBinding[] methods() {
-	if ((modifiers & AccUnresolved) == 0)
+	if ((tagBits & AreMethodsComplete) != 0)
 		return methods;
 
 	int failed = 0;
@@ -916,45 +935,59 @@
 		}
 
 		// find & report collision cases
+		boolean complyTo15 = fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5;
 		for (int i = 0, length = methods.length; i < length; i++) {
 			MethodBinding method = methods[i];
 			if (method != null) {
+				TypeBinding returnErasure = method.returnType == null ? null : method.returnType.erasure();
+				char[] selector = method.selector;
 				AbstractMethodDeclaration methodDecl = null;
-				for (int j = length - 1; j > i; j--) {
+				nextMethod : for (int j = length - 1; j > i; j--) {
 					MethodBinding method2 = methods[j];
-					if (method2 != null && CharOperation.equals(method.selector, method2.selector)) {
-						boolean paramsMatch = fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5
-							? method.areParameterErasuresEqual(method2)
-							: method.areParametersEqual(method2);
-						if (paramsMatch) {
-							boolean isEnumSpecialMethod = isEnum()
-								&& (method.selector == TypeConstants.VALUEOF || method.selector == TypeConstants.VALUES);
-							if (methodDecl == null) {
-								methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost & may still be null if method is special
-								if (methodDecl != null && methodDecl.binding != null) { // ensure its a valid user defined method
-									if (isEnumSpecialMethod)
-										scope.problemReporter().duplicateEnumSpecialMethod(this, methodDecl);
-									else
-										scope.problemReporter().duplicateMethodInType(this, methodDecl);
-									methodDecl.binding = null;
-									methods[i] = null;
-									failed++;
-								}
-							}
-							AbstractMethodDeclaration method2Decl = method2.sourceMethod();
-							if (method2Decl != null && method2Decl.binding != null) { // ensure its a valid user defined method
-								if (isEnumSpecialMethod)
-									scope.problemReporter().duplicateEnumSpecialMethod(this, method2Decl);
-								else
-									scope.problemReporter().duplicateMethodInType(this, method2Decl);
-								method2Decl.binding = null;
-								methods[j] = null;
-								failed++;
-							}
+					if (method2 == null || !CharOperation.equals(selector, method2.selector))
+						continue nextMethod;
+					if (complyTo15) {
+						if (returnErasure != (method2.returnType == null ? null : method2.returnType.erasure())) {
+							 // colllision when parameters are identical & type variable erasures match
+							if (!method.areParametersEqual(method2))
+								continue nextMethod;
+							if (method.typeVariables != NoTypeVariables && method2.typeVariables != NoTypeVariables)
+								if (!method.areTypeVariableErasuresEqual(method2))
+									continue nextMethod;
+						} else if (!method.areParameterErasuresEqual(method2)) { // colllision when parameter & return type erasures match
+							continue nextMethod;
+						}
+					} else if (!method.areParametersEqual(method2)) { // prior to 1.5, parameter identity meant a collision case
+						continue nextMethod;
+					}
+
+					// report duplicate
+					boolean isEnumSpecialMethod = isEnum()
+						&& (selector == TypeConstants.VALUEOF || selector == TypeConstants.VALUES);
+					if (methodDecl == null) {
+						methodDecl = method.sourceMethod(); // cannot be retrieved after binding is lost & may still be null if method is special
+						if (methodDecl != null && methodDecl.binding != null) { // ensure its a valid user defined method
+							if (isEnumSpecialMethod)
+								scope.problemReporter().duplicateEnumSpecialMethod(this, methodDecl);
+							else
+								scope.problemReporter().duplicateMethodInType(this, methodDecl);
+							methodDecl.binding = null;
+							methods[i] = null;
+							failed++;
 						}
 					}
+					AbstractMethodDeclaration method2Decl = method2.sourceMethod();
+					if (method2Decl != null && method2Decl.binding != null) { // ensure its a valid user defined method
+						if (isEnumSpecialMethod)
+							scope.problemReporter().duplicateEnumSpecialMethod(this, method2Decl);
+						else
+							scope.problemReporter().duplicateMethodInType(this, method2Decl);
+						method2Decl.binding = null;
+						methods[j] = null;
+						failed++;
+					}
 				}
-				if (method.returnType == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
+				if (returnErasure == null && methodDecl == null) { // forget method with invalid return type... was kept to detect possible collisions
 					method.sourceMethod().binding = null;
 					methods[i] = null;
 					failed++;
@@ -977,8 +1010,7 @@
 
 		// handle forward references to potential default abstract methods
 		addDefaultAbstractMethods();
-
-		modifiers &= ~AccUnresolved;
+		tagBits |= AreMethodsComplete;
 	}		
 	return methods;
 }
@@ -986,6 +1018,14 @@
 	if ((field.modifiers & AccUnresolved) == 0)
 		return field;
 
+	if (fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+		if ((field.getAnnotationTagBits() & AnnotationDeprecated) != 0)
+			field.modifiers |= AccDeprecated;
+		else if ((field.modifiers & AccDeprecated) != 0)
+			scope.problemReporter().missingDeprecatedAnnotationForField(field.sourceField());
+	}
+	if (isViewedAsDeprecated() && !field.isDeprecated())
+		field.modifiers |= AccDeprecatedImplicitly;	
 	FieldDeclaration[] fieldDecls = scope.referenceContext.fields;
 	for (int f = 0, length = fieldDecls.length; f < length; f++) {
 		if (fieldDecls[f].binding != field)
@@ -1018,7 +1058,8 @@
 					fieldDecls[f].binding = null;
 					return null;
 				}
-				if (fieldType instanceof ReferenceBinding && (((ReferenceBinding)fieldType).modifiers & AccGenericSignature) != 0) {
+				TypeBinding leafType = fieldType.leafComponentType();
+				if (leafType instanceof ReferenceBinding && (((ReferenceBinding)leafType).modifiers & AccGenericSignature) != 0) {
 					field.modifiers |= AccGenericSignature;
 				}				
 			} finally {
@@ -1029,10 +1070,18 @@
 	return null; // should never reach this point
 }
 private MethodBinding resolveTypesFor(MethodBinding method) {
-    
 	if ((method.modifiers & AccUnresolved) == 0)
 		return method;
 
+	if (fPackage.environment.options.sourceLevel >= ClassFileConstants.JDK1_5) {
+		if ((method.getAnnotationTagBits() & AnnotationDeprecated) != 0)
+			method.modifiers |= AccDeprecated;
+		else if ((method.modifiers & AccDeprecated) != 0)
+			scope.problemReporter().missingDeprecatedAnnotationForMethod(method.sourceMethod());
+	}
+	if (isViewedAsDeprecated() && !method.isDeprecated())
+		method.modifiers |= AccDeprecatedImplicitly;
+			
 	AbstractMethodDeclaration methodDecl = method.sourceMethod();
 	if (methodDecl == null) return null; // method could not be resolved in previous iteration
 	
@@ -1040,9 +1089,8 @@
 	if (typeParameters != null) {
 		methodDecl.scope.connectTypeVariables(typeParameters);
 		// Perform deferred bound checks for type variables (only done after type variable hierarchy is connected)
-		for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++) {
+		for (int i = 0, paramLength = typeParameters.length; i < paramLength; i++)
 			typeParameters[i].checkBounds(methodDecl.scope);
-		}
 	}
 	TypeReference[] exceptionTypes = methodDecl.thrownExceptions;
 	if (exceptionTypes != null) {
@@ -1053,9 +1101,8 @@
 		ReferenceBinding resolvedExceptionType;
 		for (int i = 0; i < size; i++) {
 			resolvedExceptionType = (ReferenceBinding) exceptionTypes[i].resolveType(methodDecl.scope, true /* check bounds*/);
-			if (resolvedExceptionType == null) {
+			if (resolvedExceptionType == null)
 				continue;
-			}
 			if (resolvedExceptionType.isGenericType() || resolvedExceptionType.isParameterizedType()) {
 				methodDecl.scope.problemReporter().invalidParameterizedExceptionType(resolvedExceptionType, exceptionTypes[i]);
 				continue;
@@ -1064,9 +1111,8 @@
 				methodDecl.scope.problemReporter().cannotThrowType(this, methodDecl, exceptionTypes[i], resolvedExceptionType);
 				continue;
 			}
-		    if ((resolvedExceptionType.modifiers & AccGenericSignature) != 0) {
+		    if ((resolvedExceptionType.modifiers & AccGenericSignature) != 0)
 				method.modifiers |= AccGenericSignature;
-			}
 			method.thrownExceptions[count++] = resolvedExceptionType;
 		}
 		if (count < size)
@@ -1090,9 +1136,9 @@
 				methodDecl.scope.problemReporter().argumentTypeCannotBeVoidArray(this, methodDecl, arg);
 				foundArgProblem = true;
 			} else {
-			    if (parameterType instanceof ReferenceBinding && (((ReferenceBinding)parameterType).modifiers & AccGenericSignature) != 0) {
+				TypeBinding leafType = parameterType.leafComponentType();
+			    if (leafType instanceof ReferenceBinding && (((ReferenceBinding)leafType).modifiers & AccGenericSignature) != 0)
 					method.modifiers |= AccGenericSignature;
-				}
 				method.parameters[i] = parameterType;
 			}
 		}
@@ -1116,9 +1162,9 @@
 				foundReturnTypeProblem = true;
 			} else {
 				method.returnType = methodType;
-				if (methodType instanceof ReferenceBinding && (((ReferenceBinding)methodType).modifiers & AccGenericSignature) != 0) {
+				TypeBinding leafType = methodType.leafComponentType();
+				if (leafType instanceof ReferenceBinding && (((ReferenceBinding)leafType).modifiers & AccGenericSignature) != 0)
 					method.modifiers |= AccGenericSignature;
-				}
 			}
 		}
 	}
@@ -1251,7 +1297,9 @@
 	buffer.append(isInterface() ? "interface " : "class "); //$NON-NLS-1$ //$NON-NLS-2$
 	buffer.append((compoundName != null) ? CharOperation.toString(compoundName) : "UNNAMED TYPE"); //$NON-NLS-1$
 
-	if (this.typeVariables != null && this.typeVariables != NoTypeVariables) {
+	if (this.typeVariables == null) {
+		buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
+	} else if (this.typeVariables != NoTypeVariables) {
 		buffer.append("\n\t<"); //$NON-NLS-1$
 		for (int i = 0, length = this.typeVariables.length; i < length; i++) {
 			if (i  > 0)
@@ -1259,8 +1307,6 @@
 			buffer.append((this.typeVariables[i] != null) ? this.typeVariables[i].toString() : "NULL TYPE VARIABLE"); //$NON-NLS-1$
 		}
 		buffer.append(">"); //$NON-NLS-1$
-	} else {
-		buffer.append("<NULL TYPE VARIABLES>"); //$NON-NLS-1$
 	}
 	buffer.append("\n\textends "); //$NON-NLS-1$
 	buffer.append((superclass != null) ? superclass.debugName() : "NULL TYPE"); //$NON-NLS-1$
@@ -1325,29 +1371,4 @@
 	for (int i = memberTypes.length; --i >= 0;)
 		 ((SourceTypeBinding) memberTypes[i]).verifyMethods(verifier);
 }
-
-/* Answer the synthetic field for <targetEnclosingType>
-*	or null if one does not exist.
-*/
-
-public FieldBinding getSyntheticField(ReferenceBinding targetEnclosingType, boolean onlyExactMatch) {
-
-	if (synthetics == null || synthetics[FIELD_EMUL] == null) return null;
-	FieldBinding field = (FieldBinding) synthetics[FIELD_EMUL].get(targetEnclosingType);
-	if (field != null) return field;
-
-	// type compatibility : to handle cases such as
-	// class T { class M{}}
-	// class S extends T { class N extends M {}} --> need to use S as a default enclosing instance for the super constructor call in N().
-	if (!onlyExactMatch){
-		Iterator accessFields = synthetics[FIELD_EMUL].values().iterator();
-		while (accessFields.hasNext()) {
-			field = (FieldBinding) accessFields.next();
-			if (CharOperation.prefixEquals(TypeConstants.SYNTHETIC_ENCLOSING_INSTANCE_PREFIX, field.name)
-				&& ((ReferenceBinding) field.type).findSuperTypeErasingTo(targetEnclosingType) != null)
-					return field;
-		}
-	}
-	return null;
-}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java
index 8d40cd0..a7cbfc0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,8 +16,18 @@
 public interface Substitution {
     
 	/**
-	 * Returns the type substitute for a given type, or itself
+	 * Returns the type substitute for a given type variable, or itself
 	 * if no substitution got performed.
 	 */
-	TypeBinding substitute(TypeBinding originalType);
+	TypeBinding substitute(TypeVariableBinding typeVariable);
+	
+	/**
+	 * Returns the lookup environment
+	 */
+	LookupEnvironment environment();
+	
+	/**
+	 * Returns true for raw substitution
+	 */
+	boolean isRawSubstitution();
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java
index 7c08f8e..47579e9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java
index ca40bca..3e08be4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,9 +13,12 @@
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 
 public class SyntheticFieldBinding extends FieldBinding {
+	
 	public int index;
-public SyntheticFieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant, int index) {
-	super(name, type, modifiers, declaringClass, constant);
-	this.index = index;
-}
+	
+	public SyntheticFieldBinding(char[] name, TypeBinding type, int modifiers, ReferenceBinding declaringClass, Constant constant, int index) {
+		super(name, type, modifiers, declaringClass, constant);
+		this.index = index;
+		this.tagBits |= TagBits.AnnotationResolved;
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
index f256cdd..0f10dd6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -37,6 +37,7 @@
 	public SyntheticMethodBinding(FieldBinding targetField, boolean isReadAccess, ReferenceBinding declaringClass) {
 
 		this.modifiers = AccDefault | AccStatic | AccSynthetic;
+		this.tagBits |= TagBits.AnnotationResolved;
 		SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
 		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
 		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
@@ -139,18 +140,19 @@
 	/**
 	 * Construct a bridge method
 	 */
-	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, MethodBinding localTargetMethod) {
+	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, MethodBinding targetMethod, SourceTypeBinding declaringClass) {
 		
-	    this.declaringClass = localTargetMethod.declaringClass;
+	    this.declaringClass = declaringClass;
 	    this.selector = overridenMethodToBridge.selector;
 	    this.modifiers = overridenMethodToBridge.modifiers | AccBridge | AccSynthetic;
+		this.tagBits |= TagBits.AnnotationResolved;
 	    this.modifiers &= ~(AccAbstract | AccNative);
 	    this.returnType = overridenMethodToBridge.returnType;
 	    this.parameters = overridenMethodToBridge.parameters;
 	    this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
-	    this.targetMethod = localTargetMethod;
+	    this.targetMethod = targetMethod;
 	    this.kind = BridgeMethod;
-		SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
+		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
 		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
 		this.index = methodId;	    
 	}
@@ -159,28 +161,25 @@
 	 * Construct enum special methods: values or valueOf methods
 	 */
 	public SyntheticMethodBinding(SourceTypeBinding declaringEnum, char[] selector) {
+	    this.declaringClass = declaringEnum;
+	    this.selector = selector;
+	    this.modifiers = AccFinal | AccPublic | AccStatic;
+		this.tagBits |= TagBits.AnnotationResolved;
+	    this.thrownExceptions = NoExceptions;
 		if (selector == TypeConstants.VALUES) {
-		    this.declaringClass = declaringEnum;
-		    this.selector = selector;
-		    this.modifiers = AccFinal | AccPublic | AccStatic;
 		    this.returnType = declaringEnum.scope.createArrayType(declaringEnum, 1);
 		    this.parameters = NoParameters;
-		    this.thrownExceptions = NoExceptions;
 		    this.kind = EnumValues;
-			SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
-			int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
-			this.index = methodId;	    
 		} else if (selector == TypeConstants.VALUEOF) {
-		    this.declaringClass = declaringEnum;
-		    this.selector = selector;
-		    this.modifiers = AccFinal | AccPublic | AccStatic;
 		    this.returnType = declaringEnum;
 		    this.parameters = new TypeBinding[]{ declaringEnum.scope.getJavaLangString() };
-		    this.thrownExceptions = NoExceptions;
 		    this.kind = EnumValueOf;
-			SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
-			int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
-			this.index = methodId;	    
+		}
+		SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
+		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
+		this.index = methodId;	    
+		if (declaringEnum.isStrictfp()) {
+			this.modifiers |= AccStrictfp;
 		}
 	}
 
@@ -192,6 +191,7 @@
 	
 		this.targetMethod = accessedConstructor;
 		this.modifiers = AccDefault | AccSynthetic;
+		this.tagBits |= TagBits.AnnotationResolved;
 		SourceTypeBinding sourceType = (SourceTypeBinding) accessedConstructor.declaringClass; 
 		SyntheticMethodBinding[] knownSyntheticMethods = 
 			sourceType.syntheticMethods(); 
@@ -271,6 +271,7 @@
 		
 		this.targetMethod = accessedMethod;
 		this.modifiers = AccDefault | AccStatic | AccSynthetic;
+		this.tagBits |= TagBits.AnnotationResolved;
 		SourceTypeBinding declaringSourceType = (SourceTypeBinding) receiverType;
 		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
 		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
index ffc6b55..d525014 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -49,7 +49,7 @@
 
 	// set for parameterized type NOT of the form X<?,?>
 	long IsBoundParameterizedType = ASTNode.Bit24; 
-
+	
 	// used by BinaryTypeBinding
 	long HasUnresolvedTypeVariables = ASTNode.Bit25;
 	long HasUnresolvedSuperclass = ASTNode.Bit26;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
index 43455eb..eb1201d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -68,19 +68,21 @@
 public boolean canBeInstantiated() {
 	return !isBaseType();
 }
+
+/**
+ * Perform capture conversion on a given type (only effective on parameterized type with wildcards)
+ */
+public TypeBinding capture() {
+	return this;
+}
+
 /**
  * Collect the substitutes into a map for certain type variables inside the receiver type
  * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
  */
-public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
+public void collectSubstitutes(Scope scope, TypeBinding otherType, Map substitutes, int constraint) {
     // no substitute by default
 }
-/*
- * genericTypeSignature
- */
-public char[] computeUniqueKey() {
-	return genericTypeSignature();
-}
 /**
  *  Answer the receiver's constant pool name.
  *  NOTE: This method should only be used during/after code gen.
@@ -111,7 +113,6 @@
  */
 public TypeBinding genericCast(TypeBinding otherType) {
     if (this == otherType) return null;
-	if (otherType.isWildcard() && ((WildcardBinding)otherType).kind != Wildcard.EXTENDS) return null;
 	TypeBinding otherErasure = otherType.erasure();
 	if (otherErasure == this.erasure()) return null;
 	return otherErasure;
@@ -147,6 +148,14 @@
 public boolean isBoundParameterizedType() {
 	return (this.tagBits & TagBits.IsBoundParameterizedType) != 0;
 }
+
+/**
+ * Returns true if the type is the capture of some wildcard
+ */
+public boolean isCapture() {
+    return false;
+}
+
 public boolean isClass() {
 	return false;
 }
@@ -213,19 +222,10 @@
 public boolean isParameterizedType() {
     return false;
 }
-	
-public boolean isPartOfRawType() {
-	TypeBinding current = this;
-	do {
-		if (current.isRawType())
-			return true;
-	} while ((current = current.enclosingType()) != null);
-    return false;
-}
 
 /**
  * Returns true if the two types are statically known to be different at compile-time,
- * e.g. a type variable is not probably known to be distinct from another type
+ * e.g. a type variable is not provably known to be distinct from another type
  */
 public boolean isProvablyDistinctFrom(TypeBinding otherType, int depth) {
 	if (this == otherType) return false;
@@ -314,7 +314,7 @@
 	TypeBinding upperBound = this;
 	if (isWildcard()) {
 		WildcardBinding wildcard = (WildcardBinding) this;
-		switch(wildcard.kind) {
+		switch(wildcard.boundKind) {
 			case Wildcard.EXTENDS :
 				upperBound = wildcard.bound;
 				lowerBound = null;
@@ -330,7 +330,8 @@
 	}
 	if (otherArgument.isWildcard()) {
 		WildcardBinding otherWildcard = (WildcardBinding) otherArgument;
-		switch(otherWildcard.kind) {
+		if (otherWildcard.otherBounds != null) return false; // not a true wildcard (intersection type)
+		switch(otherWildcard.boundKind) {
 			case Wildcard.EXTENDS:
 				return upperBound != null && upperBound.isCompatibleWith(otherWildcard.bound);
 
@@ -368,6 +369,25 @@
  * Meant to be invoked on compatible types, to figure if unchecked conversion is necessary
  */
 public boolean needsUncheckedConversion(TypeBinding targetType) {
+
+	if (this == targetType) return false;
+	targetType = targetType.leafComponentType();
+	if (!(targetType instanceof ReferenceBinding)) 
+		return false;
+
+	TypeBinding currentType = this.leafComponentType();
+	if (!(currentType instanceof ReferenceBinding))
+		return false;
+	
+	ReferenceBinding compatible = ((ReferenceBinding)currentType).findSuperTypeErasingTo((ReferenceBinding)targetType.erasure());
+	if (compatible == null) 
+		return false;
+	if (!compatible.isPartOfRawType()) return false;
+	do {
+		if (compatible.isRawType() && (targetType.isBoundParameterizedType() || targetType.isGenericType())) {
+			return true;
+		}
+	} while ((compatible = compatible.enclosingType()) != null && (targetType = targetType.enclosingType()) != null);
 	return false;
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
index 3a31669..a154f81 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,6 +41,8 @@
     char[] WILDCARD_MINUS = { '-' };
     char[] WILDCARD_STAR = { '*' };
     char[] WILDCARD_PLUS = { '+' };
+    char[] WILDCARD_CAPTURE_NAME = "capture-of ".toCharArray(); //$NON-NLS-1$
+	char[] WILDCARD_CAPTURE = { '!' };
 	char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
 	char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
 	char[] INT = "int".toCharArray(); //$NON-NLS-1$
@@ -117,8 +119,19 @@
 	int EqualOrMoreSpecific = -1;
 	int NotRelated = 0;
 	int MoreGeneric = 1;
+	
+    // Constraints for generic type argument inference
+    int CONSTRAINT_EQUAL = 0;		// Actual = Formal
+    int CONSTRAINT_EXTENDS = 1;	// Actual << Formal
+    int CONSTRAINT_SUPER = 2;		// Actual >> Formal
+	
+	// Constants used to perform bound checks
+	int OK = 0;
+	int UNCHECKED = 1;
+	int MISMATCH = 2;
 
 	// Shared binding collections
+	TypeBinding[] NoTypes = new TypeBinding[0];
 	TypeBinding[] NoParameters = new TypeBinding[0];
 	ReferenceBinding[] NoExceptions = new ReferenceBinding[0];
 	ReferenceBinding[] AnyException = new ReferenceBinding[] { null }; // special handler for all exceptions
@@ -137,4 +150,7 @@
 	char[] SYNTHETIC_OUTER_LOCAL_PREFIX = "val$".toCharArray(); //$NON-NLS-1$
 	char[] SYNTHETIC_ENCLOSING_INSTANCE_PREFIX = "this$".toCharArray(); //$NON-NLS-1$
 	char[] SYNTHETIC_ACCESS_METHOD_PREFIX =  "access$".toCharArray(); //$NON-NLS-1$
+	
+	// synthetic package-info name
+	public static final char[] PACKAGE_INFO_NAME = "package-info".toCharArray(); //$NON-NLS-1$	
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
index 0e8beeb..821214e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
index 7292cf2..ea3b3dc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v0.5 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import java.util.Map;
@@ -26,7 +26,7 @@
 	 * Denote the first explicit (binding) bound amongst the supertypes (from declaration in source)
 	 * If no superclass was specified, then it denotes the first superinterface, or null if none was specified.
 	 */
-	public ReferenceBinding firstBound; 
+	public TypeBinding firstBound; 
 
 	// actual resolved variable supertypes (if no superclass bound, then associated to Object)
 	public ReferenceBinding superclass;
@@ -48,36 +48,59 @@
 	/**
 	 * Returns true if the argument type satisfies all bounds of the type parameter
 	 */
-	public boolean boundCheck(Substitution substitution, TypeBinding argumentType) {
-		if (argumentType == NullBinding || this == argumentType) 
-			return true;
+	public int boundCheck(Substitution substitution, TypeBinding argumentType) {
+
+		if (argumentType == NullBinding || argumentType == this)
+			return TypeConstants.OK;
+		boolean hasSubstitution = substitution != null;
 		if (!(argumentType instanceof ReferenceBinding || argumentType.isArrayType()))
-			return false;	
+			return TypeConstants.MISMATCH;	
 		
 	    if (argumentType.isWildcard()) {
 	        WildcardBinding wildcard = (WildcardBinding) argumentType;
-	        switch (wildcard.kind) {
+	        switch (wildcard.boundKind) {
 	        	case Wildcard.SUPER :
-		            if (!boundCheck(substitution, wildcard.bound)) return false;
-		            break;
+//		            if (boundCheck(substitution, wildcard.bound) != TypeConstants.OK) return TypeConstants.MISMATCH;
+//		            break;
+		            return boundCheck(substitution, wildcard.bound); // only check the lower bound
 				case Wildcard.UNBOUND :
 					if (this == wildcard.typeVariable()) 
-						return true;
+						return TypeConstants.OK;
 					break;	        		
 	        }
 	    }
-//		if (this == argumentType) 
-//			return true;
-		boolean hasSubstitution = substitution != null;
-		if (this.superclass.id != T_JavaLangObject && !argumentType.isCompatibleWith(hasSubstitution ? substitution.substitute(this.superclass) : this.superclass)) {
-		    return false;
+		boolean unchecked = false;
+		if (this.superclass.id != T_JavaLangObject) {
+			TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superclass) : this.superclass;
+			if (!argumentType.isCompatibleWith(substitutedSuperType)) {
+			    return TypeConstants.MISMATCH;
+			}
+			if (argumentType instanceof ReferenceBinding) {
+				ReferenceBinding referenceArgument = (ReferenceBinding) argumentType;
+				TypeBinding match = referenceArgument.findSuperTypeErasingTo((ReferenceBinding)substitutedSuperType.erasure());
+				if (match != null){
+					// Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
+					if (match.isRawType() && (substitutedSuperType.isGenericType()||substitutedSuperType.isBoundParameterizedType()))
+						unchecked = true;
+				}
+			}
 		}
 	    for (int i = 0, length = this.superInterfaces.length; i < length; i++) {
-	        if (!argumentType.isCompatibleWith(hasSubstitution ? substitution.substitute(this.superInterfaces[i]) : this.superInterfaces[i])) {
-				return false;
-	        }
+			TypeBinding substitutedSuperType = hasSubstitution ? Scope.substitute(substitution, this.superInterfaces[i]) : this.superInterfaces[i];
+			if (!argumentType.isCompatibleWith(substitutedSuperType)) {
+			    return TypeConstants.MISMATCH;
+			}
+			if (argumentType instanceof ReferenceBinding) {
+				ReferenceBinding referenceArgument = (ReferenceBinding) argumentType;
+				TypeBinding match = referenceArgument.findSuperTypeErasingTo((ReferenceBinding)substitutedSuperType.erasure());
+				if (match != null){
+					// Enum#RAW is not a substitute for <E extends Enum<E>> (86838)
+					if (match.isRawType() && (substitutedSuperType.isGenericType()||substitutedSuperType.isBoundParameterizedType()))
+						unchecked = true;
+				}
+			}
 	    }
-	    return true;
+	    return unchecked ? TypeConstants.UNCHECKED : TypeConstants.OK;
 	}
 	
 	/**
@@ -88,27 +111,57 @@
 	}
 	/**
 	 * Collect the substitutes into a map for certain type variables inside the receiver type
-	 * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
+	 * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
 	 */
-	public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
+	public void collectSubstitutes(Scope scope, TypeBinding otherType, Map substitutes, int constraint) {
+		
 		// cannot infer anything from a null type
 		if (otherType == NullBinding) return;
+	
+		if (otherType.isBaseType()) {
+			TypeBinding boxedType = scope.environment().computeBoxingType(otherType);
+			if (boxedType == otherType) return;
+			otherType = boxedType;
+		}
 		
-	    TypeBinding[] variableSubstitutes = (TypeBinding[])substitutes.get(this);
+		// reverse constraint, to reflect variable on rhs:   A << T --> T >: A
+		int variableConstraint;
+		switch(constraint) {
+			case CONSTRAINT_EQUAL :
+				variableConstraint = CONSTRAINT_EQUAL;
+				break;
+			case CONSTRAINT_EXTENDS :
+				variableConstraint = CONSTRAINT_SUPER;
+				break;
+			default:
+			//case CONSTRAINT_SUPER :
+				variableConstraint = CONSTRAINT_EXTENDS;
+				break;
+		}
+	    TypeBinding[][] variableSubstitutes = (TypeBinding[][])substitutes.get(this);
 	    if (variableSubstitutes != null) {
-	        int length = variableSubstitutes.length;
-	        for (int i = 0; i < length; i++) {
-	        	TypeBinding substitute = variableSubstitutes[i];
-	            if (substitute == otherType) return; // already there
-	            if (substitute == null) {
-	                variableSubstitutes[i] = otherType;
-	                return;
-	            }
-	        }
-	        // no free spot found, need to grow
-	        System.arraycopy(variableSubstitutes, 0, variableSubstitutes = new TypeBinding[2*length], 0, length);
-	        variableSubstitutes[length] = otherType;
-	        substitutes.put(this, variableSubstitutes);
+		    insertLoop: {
+		    	TypeBinding[] constraintSubstitutes = variableSubstitutes[variableConstraint];
+		    	int length;
+		    	if (constraintSubstitutes == null) {
+		    		length = 0;
+		    		constraintSubstitutes = new TypeBinding[1];
+		    	} else {
+		    		length = constraintSubstitutes.length;
+			        for (int i = 0; i < length; i++) {
+			        	TypeBinding substitute = constraintSubstitutes[i];
+			            if (substitute == otherType) return; // already there
+			            if (substitute == null) {
+			                constraintSubstitutes[i] = otherType;
+			                break insertLoop;
+			            }
+			        }
+			        // no free spot found, need to grow
+			        System.arraycopy(constraintSubstitutes, 0, constraintSubstitutes = new TypeBinding[2*length], 0, length);
+		    	}
+		        constraintSubstitutes[length] = otherType;
+		        variableSubstitutes[variableConstraint] = constraintSubstitutes;
+		    }
 	    }
 	}
 	
@@ -122,8 +175,8 @@
 	 * declaringUniqueKey : genericTypeSignature
 	 * p.X<T> { ... } --> Lp/X<TT;>;:TT;
 	 */
-	public char[] computeUniqueKey() {
-		char[] declaringKey = this.declaringElement.computeUniqueKey();
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+		char[] declaringKey = this.declaringElement.computeUniqueKey(false/*without access flags*/);
 		int declaringLength = declaringKey.length;
 		char[] sig = genericTypeSignature();
 		int sigLength = sig.length;
@@ -199,7 +252,7 @@
 
     if (this == erasure) return this;
     ReferenceBinding currentType = this;
-    if (erasure.isClass()) {
+    if (!erasure.isInterface()) {
 		while ((currentType = currentType.superclass()) != null) {
 			if (currentType == erasure || currentType.erasure() == erasure) return currentType;
 		}
@@ -279,6 +332,28 @@
 	public boolean isTypeVariable() {
 	    return true;
 	}
+	
+	/** 
+	 * Returns the original type variable for a given variable.
+	 * Only different from receiver for type variables of generic methods of parameterized types
+	 * e.g. X<U> {   <V1 extends U> U foo(V1)   } --> X<String> { <V2 extends String> String foo(V2)  }  
+	 *         and V2.original() --> V1
+	 */
+	public TypeVariableBinding original() {
+		if (this.declaringElement.kind() == Binding.METHOD) {
+			MethodBinding originalMethod = ((MethodBinding)this.declaringElement).original();
+			if (originalMethod != this.declaringElement) {
+				return originalMethod.typeVariables[this.rank];
+			}
+		} else {
+			ReferenceBinding originalType = (ReferenceBinding)((ReferenceBinding)this.declaringElement).erasure();
+			if (originalType != this.declaringElement) {
+				return originalType.typeVariables()[this.rank];
+			}
+		}
+		return this;
+	}
+	
 	/**
      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#readableName()
      */
@@ -289,23 +364,34 @@
 	ReferenceBinding resolve(LookupEnvironment environment) {
 		if ((this.modifiers & AccUnresolved) == 0)
 			return this;
-	
+
+		TypeBinding oldSuperclass = this.superclass, oldFirstInterface = null;
 		if (this.superclass != null)
 			this.superclass = BinaryTypeBinding.resolveUnresolvedType(this.superclass, environment, true);
-		if (this.firstBound != null)
-			this.firstBound = BinaryTypeBinding.resolveUnresolvedType(this.firstBound, environment, true);
 		ReferenceBinding[] interfaces = this.superInterfaces;
-		for (int i = interfaces.length; --i >= 0;)
-			interfaces[i] = BinaryTypeBinding.resolveUnresolvedType(interfaces[i], environment, true);
+		int length;
+		if ((length = interfaces.length) != 0) {
+			oldFirstInterface = interfaces[0];
+			for (int i = length; --i >= 0;) {
+				interfaces[i] = BinaryTypeBinding.resolveUnresolvedType(interfaces[i], environment, true);
+			}
+		}
 		this.modifiers &= ~AccUnresolved;
 	
 		// finish resolving the types
 		if (this.superclass != null)
 			this.superclass = BinaryTypeBinding.resolveType(this.superclass, environment, true);
-		if (this.firstBound != null)
-			this.firstBound = BinaryTypeBinding.resolveType(this.firstBound, environment, true);
 		for (int i = interfaces.length; --i >= 0;)
 			interfaces[i] = BinaryTypeBinding.resolveType(interfaces[i], environment, true);
+
+		// refresh the firstBound in case it changed
+		if (this.firstBound != null) {
+			if (this.firstBound == oldSuperclass) {
+				this.firstBound = this.superclass;
+			} else if (this.firstBound == oldFirstInterface) {
+				this.firstBound = interfaces[0];
+			}
+		}
 		return this;
 	}
 	
@@ -344,4 +430,4 @@
 		buffer.append('>');
 		return buffer.toString();
 	}	
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
index 3b4e74b..bef72ed 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UpdatedMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UpdatedMethodBinding.java
index 485c159..11739e2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UpdatedMethodBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/UpdatedMethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
index 00bf26f..89514aa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
index 5e7de03..eeb487c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000-2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,8 +24,9 @@
 	ReferenceBinding genericType;
 	int rank;
     public TypeBinding bound; // when unbound denotes the corresponding type variable (so as to retrieve its bound lazily)
+    public TypeBinding[] otherBounds; // only positionned by lub computations (if so, #bound is also set) and associated to EXTENDS mode
 	char[] genericSignature;
-	public int kind;
+	public int boundKind;
 	ReferenceBinding superclass;
 	ReferenceBinding[] superInterfaces;
 	TypeVariableBinding typeVariable; // corresponding variable
@@ -34,18 +35,19 @@
 	/**
 	 * When unbound, the bound denotes the corresponding type variable (so as to retrieve its bound lazily)
 	 */
-	public WildcardBinding(ReferenceBinding genericType, int rank, TypeBinding bound, int kind, LookupEnvironment environment) {
+	public WildcardBinding(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind, LookupEnvironment environment) {
 		this.genericType = genericType;
 		this.rank = rank;
-	    this.kind = kind;
+	    this.boundKind = boundKind;
 		this.modifiers = AccPublic | AccGenericSignature; // treat wildcard as public
 		this.environment = environment;
-		initialize(genericType, bound);
+		initialize(genericType, bound, otherBounds);
 
 		if (genericType instanceof UnresolvedReferenceBinding)
 			((UnresolvedReferenceBinding) genericType).addWrapper(this);
 		if (bound instanceof UnresolvedReferenceBinding)
 			((UnresolvedReferenceBinding) bound).addWrapper(this);
+		this.tagBits |=  HasUnresolvedTypeVariables; // cleared in resolve()
 	}
 
 	public int kind() {
@@ -56,16 +58,19 @@
 	 * Returns true if the argument type satisfies all bounds of the type parameter
 	 */
 	public boolean boundCheck(TypeBinding argumentType) {
-	    switch (this.kind) {
+	    switch (this.boundKind) {
 	        case Wildcard.UNBOUND :
 	            return true;
 	        case Wildcard.EXTENDS :
-	            return argumentType.isCompatibleWith(this.bound);
+	            if (argumentType.isCompatibleWith(this.bound)) return true;
+	            // check other bounds (lub scenario)
+            	for (int i = 0, length = this.otherBounds == null ? 0 : this.otherBounds.length; i < length; i++) {
+            		if (argumentType.isCompatibleWith(this.otherBounds[i])) return true;
+            	}
+            	return false;
 	        default: // SUPER
-	        	// allowed as long as one is compatible with other (either way)
 	        	// ? super Exception   ok for:  IOException, since it would be ok for (Exception)ioException
-	            return this.bound.isCompatibleWith(argumentType)
-					|| argumentType.isCompatibleWith(this.bound);
+	            return argumentType.isCompatibleWith(this.bound);
 	    }
     }
 	/**
@@ -77,22 +82,197 @@
 	}
 	/**
 	 * Collect the substitutes into a map for certain type variables inside the receiver type
-	 * e.g.   Collection<T>.findSubstitute(T, Collection<List<X>>):   T --> List<X>
+	 * e.g.   Collection<T>.collectSubstitutes(Collection<List<X>>, Map), will populate Map with: T --> List<X>
 	 */
-	public void collectSubstitutes(TypeBinding otherType, Map substitutes) {
+	public void collectSubstitutes(Scope scope, TypeBinding otherType, Map substitutes, int constraint) {
 
-		if (this.bound == null)
-			return;
-		if (otherType.isWildcard()) {
-			WildcardBinding otherWildcard = (WildcardBinding) otherType;
-			if (otherWildcard.bound != null) {
-				this.bound.collectSubstitutes(otherWildcard.bound, substitutes);
-			}
-		} else {
-            this.bound.collectSubstitutes(otherType, substitutes);
-		}	    
+		if ((this.tagBits & TagBits.HasTypeVariable) == 0) return;
+		if (otherType == NullBinding) return;
+	
+		if (otherType.isCapture()) {
+			CaptureBinding capture = (CaptureBinding) otherType;
+			otherType = capture.wildcard;
+		}
+		
+		switch (constraint) {
+			case CONSTRAINT_EXTENDS : // A << F
+				switch (this.boundKind) {
+					case Wildcard.UNBOUND: // F={?}
+//						if (otherType.isWildcard()) {
+//							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+//							switch(otherWildcard.kind) {
+//								case Wildcard.UNBOUND: // A={?} << F={?}  --> 0
+//									break;
+//								case Wildcard.EXTENDS: // A={? extends V} << F={?} ---> 0
+//									break;
+//								case Wildcard.SUPER: // A={? super V} << F={?} ---> 0
+//									break;
+//							}
+//						} else { // A=V << F={?} ---> 0
+//						}
+						break;
+					case Wildcard.EXTENDS: // F={? extends U}
+						if (otherType.isWildcard()) {
+							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+							switch(otherWildcard.boundKind) {
+								case Wildcard.UNBOUND: // A={?} << F={? extends U}  --> 0
+									break;
+								case Wildcard.EXTENDS: // A={? extends V} << F={? extends U} ---> V << U
+									this.bound.collectSubstitutes(scope, otherWildcard.bound, substitutes, CONSTRAINT_EXTENDS);
+						        	for (int i = 0, length = otherWildcard.otherBounds == null ? 0 : otherWildcard.otherBounds.length; i < length; i++) {
+										this.bound.collectSubstitutes(scope, otherWildcard.otherBounds[i], substitutes, CONSTRAINT_EXTENDS);
+						        	}									
+									break;
+								case Wildcard.SUPER: // A={? super V} << F={? extends U} ---> 0
+									break;
+							}
+						} else { // A=V << F={? extends U} ---> V << U
+							this.bound.collectSubstitutes(scope, otherType, substitutes, CONSTRAINT_EXTENDS);
+						}
+						break;
+					case Wildcard.SUPER: // F={? super U}
+						if (otherType.isWildcard()) {
+							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+							switch(otherWildcard.boundKind) {
+								case Wildcard.UNBOUND: // A={?} << F={? super U}  --> 0
+									break;
+								case Wildcard.EXTENDS: // A={? extends V} << F={? super U} ---> 0
+									break;
+								case Wildcard.SUPER: // A={? super V} << F={? super U} ---> 0
+									this.bound.collectSubstitutes(scope, otherWildcard.bound, substitutes, CONSTRAINT_SUPER);
+						        	for (int i = 0, length = otherWildcard.otherBounds == null ? 0 : otherWildcard.otherBounds.length; i < length; i++) {
+										this.bound.collectSubstitutes(scope, otherWildcard.otherBounds[i], substitutes, CONSTRAINT_SUPER);
+						        	}									
+									break;
+							}
+						} else { // A=V << F={? super U} ---> V >> U
+							this.bound.collectSubstitutes(scope, otherType, substitutes, CONSTRAINT_SUPER);							
+						}						
+						break;
+				}
+				break;
+			case CONSTRAINT_EQUAL : // A == F
+				switch (this.boundKind) {
+					case Wildcard.UNBOUND: // F={?}
+//						if (otherType.isWildcard()) {
+//							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+//							switch(otherWildcard.kind) {
+//								case Wildcard.UNBOUND: // A={?} == F={?}  --> 0
+//									break;
+//								case Wildcard.EXTENDS: // A={? extends V} == F={?} ---> 0
+//									break;
+//								case Wildcard.SUPER: // A={? super V} == F={?} ---> 0
+//									break;
+//							}
+//						} else { // A=V == F={?} ---> 0
+//						}
+						break;
+					case Wildcard.EXTENDS: // F={? extends U}
+						if (otherType.isWildcard()) {
+							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+							switch(otherWildcard.boundKind) {
+								case Wildcard.UNBOUND: // A={?} == F={? extends U}  --> 0
+									break;
+								case Wildcard.EXTENDS: // A={? extends V} == F={? extends U} ---> V == U
+									this.bound.collectSubstitutes(scope, otherWildcard.bound, substitutes, CONSTRAINT_EQUAL);
+						        	for (int i = 0, length = otherWildcard.otherBounds == null ? 0 : otherWildcard.otherBounds.length; i < length; i++) {
+										this.bound.collectSubstitutes(scope, otherWildcard.otherBounds[i], substitutes, CONSTRAINT_EQUAL);
+						        	}											
+									break;
+								case Wildcard.SUPER: // A={? super V} == F={? extends U} ---> 0
+									break;
+							}
+						} else { // A=V == F={? extends U} ---> 0
+						}
+						break;
+					case Wildcard.SUPER: // F={? super U}
+						if (otherType.isWildcard()) {
+							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+							switch(otherWildcard.boundKind) {
+								case Wildcard.UNBOUND: // A={?} == F={? super U}  --> 0
+									break;
+								case Wildcard.EXTENDS: // A={? extends V} == F={? super U} ---> 0
+									break;
+								case Wildcard.SUPER: // A={? super V} == F={? super U} ---> 0
+									this.bound.collectSubstitutes(scope, otherWildcard.bound, substitutes, CONSTRAINT_EQUAL);
+						        	for (int i = 0, length = otherWildcard.otherBounds == null ? 0 : otherWildcard.otherBounds.length; i < length; i++) {
+										this.bound.collectSubstitutes(scope, otherWildcard.otherBounds[i], substitutes, CONSTRAINT_EQUAL);
+						        	}	
+						        	break;
+							}
+						} else { // A=V == F={? super U} ---> 0
+						}						
+						break;
+				}
+				break;
+			case CONSTRAINT_SUPER : // A >> F
+				switch (this.boundKind) {
+					case Wildcard.UNBOUND: // F={?}
+//						if (otherType.isWildcard()) {
+//							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+//							switch(otherWildcard.kind) {
+//								case Wildcard.UNBOUND: // A={?} >> F={?}  --> 0
+//									break;
+//								case Wildcard.EXTENDS: // A={? extends V} >> F={?} ---> 0
+//									break;
+//								case Wildcard.SUPER: // A={? super V} >> F={?} ---> 0
+//									break;
+//							}
+//						} else { // A=V >> F={?} ---> 0
+//						}
+						break;
+					case Wildcard.EXTENDS: // F={? extends U}
+						if (otherType.isWildcard()) {
+							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+							switch(otherWildcard.boundKind) {
+								case Wildcard.UNBOUND: // A={?} >> F={? extends U}  --> 0
+									break;
+								case Wildcard.EXTENDS: // A={? extends V} >> F={? extends U} ---> V >> U
+									this.bound.collectSubstitutes(scope, otherWildcard.bound, substitutes, CONSTRAINT_SUPER);
+						        	for (int i = 0, length = otherWildcard.otherBounds == null ? 0 : otherWildcard.otherBounds.length; i < length; i++) {
+										this.bound.collectSubstitutes(scope, otherWildcard.otherBounds[i], substitutes, CONSTRAINT_SUPER);
+						        	}										
+									break;
+								case Wildcard.SUPER: // A={? super V} >> F={? extends U} ---> 0
+									break;
+							}
+						} else { // A=V == F={? extends U} ---> 0
+						}
+						break;
+					case Wildcard.SUPER: // F={? super U}
+						if (otherType.isWildcard()) {
+							WildcardBinding otherWildcard = (WildcardBinding) otherType;
+							switch(otherWildcard.boundKind) {
+								case Wildcard.UNBOUND: // A={?} >> F={? super U}  --> 0
+									break;
+								case Wildcard.EXTENDS: // A={? extends V} >> F={? super U} ---> 0
+									break;
+								case Wildcard.SUPER: // A={? super V} >> F={? super U} ---> V >> U
+									this.bound.collectSubstitutes(scope, otherWildcard.bound, substitutes, CONSTRAINT_SUPER);
+						        	for (int i = 0, length = otherWildcard.otherBounds == null ? 0 : otherWildcard.otherBounds.length; i < length; i++) {
+										this.bound.collectSubstitutes(scope, otherWildcard.otherBounds[i], substitutes, CONSTRAINT_SUPER);
+						        	}	
+						        	break;
+							}
+						} else { // A=V >> F={? super U} ---> 0
+						}						
+						break;
+				}
+				break;
+		}
 	}
 	
+	public char[] computeUniqueKey(boolean withAccessFlags) {
+        switch (this.boundKind) {
+            case Wildcard.UNBOUND : 
+                return WILDCARD_STAR;
+            case Wildcard.EXTENDS :
+                return CharOperation.concat(WILDCARD_PLUS, this.bound.computeUniqueKey(false/*without access flags*/));
+			default: // SUPER
+			    return CharOperation.concat(WILDCARD_MINUS, this.bound.computeUniqueKey(false/*without access flags*/));
+        }
+       }
+	
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#debugName()
 	 */
@@ -104,7 +284,7 @@
      * @see org.eclipse.jdt.internal.compiler.lookup.TypeBinding#erasure()
      */
     public TypeBinding erasure() {
-    	if (this.kind == Wildcard.EXTENDS)
+    	if (this.boundKind == Wildcard.EXTENDS)
 	        return this.bound.erasure();
     	return typeVariable().erasure();
     }
@@ -114,7 +294,7 @@
      */
     public char[] genericTypeSignature() {
         if (this.genericSignature == null) {
-            switch (this.kind) {
+            switch (this.boundKind) {
                 case Wildcard.UNBOUND : 
                     this.genericSignature = WILDCARD_STAR;
                     break;
@@ -132,9 +312,10 @@
 		return this.genericType.hashCode();
 	}
 
-	void initialize(ReferenceBinding someGenericType, TypeBinding someBound) {
+	void initialize(ReferenceBinding someGenericType, TypeBinding someBound, TypeBinding[] someOtherBounds) {
 		this.genericType = someGenericType;
 		this.bound = someBound;
+		this.otherBounds = someOtherBounds;
 		if (someGenericType != null) {
 			this.fPackage = someGenericType.getPackage();
 		}
@@ -148,7 +329,7 @@
      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#isSuperclassOf(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)
      */
     public boolean isSuperclassOf(ReferenceBinding otherType) {
-        if (this.kind == Wildcard.SUPER) {
+        if (this.boundKind == Wildcard.SUPER) {
             if (this.bound instanceof ReferenceBinding) {
                 return ((ReferenceBinding) this.bound).isSuperclassOf(otherType);
             } else { // array bound
@@ -162,7 +343,7 @@
 	 * Returns true if the type is a wildcard
 	 */
 	public boolean isUnboundWildcard() {
-	    return this.kind == Wildcard.UNBOUND;
+	    return this.boundKind == Wildcard.UNBOUND;
 	}
 	
     /**
@@ -176,19 +357,33 @@
      * @see org.eclipse.jdt.internal.compiler.lookup.Binding#readableName()
      */
     public char[] readableName() {
-        switch (this.kind) {
+        switch (this.boundKind) {
             case Wildcard.UNBOUND : 
                 return WILDCARD_NAME;
             case Wildcard.EXTENDS :
-                return CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, this.bound.readableName());
+            	if (this.otherBounds == null) 
+	                return CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, this.bound.readableName());
+            	StringBuffer buffer = new StringBuffer(10);
+            	buffer.append(this.bound.readableName());
+            	for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+            		buffer.append('&').append(this.otherBounds[i].readableName());
+            	}
+            	int length;
+				char[] result = new char[length = buffer.length()];
+				buffer.getChars(0, length, result, 0);
+				return result;	            	
 			default: // SUPER
 			    return CharOperation.concat(WILDCARD_NAME, WILDCARD_SUPER, this.bound.readableName());
         }
     }
     
 	ReferenceBinding resolve() {
+		if ((this.tagBits & HasUnresolvedTypeVariables) == 0)
+			return this;
+
+		this.tagBits &= ~HasUnresolvedTypeVariables;
 		BinaryTypeBinding.resolveType(this.genericType, this.environment, null, 0);
-	    switch(this.kind) {
+	    switch(this.boundKind) {
 	        case Wildcard.EXTENDS :
 	        case Wildcard.SUPER :
 				BinaryTypeBinding.resolveType(this.bound, this.environment, null, 0);
@@ -202,11 +397,21 @@
      * @see org.eclipse.jdt.internal.compiler.lookup.Binding#shortReadableName()
      */
     public char[] shortReadableName() {
-        switch (this.kind) {
+        switch (this.boundKind) {
             case Wildcard.UNBOUND : 
                 return WILDCARD_NAME;
             case Wildcard.EXTENDS :
-                return CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, this.bound.shortReadableName());
+            	if (this.otherBounds == null) 
+	                return CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, this.bound.shortReadableName());
+            	StringBuffer buffer = new StringBuffer(10);
+            	buffer.append(this.bound.shortReadableName());
+            	for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+            		buffer.append('&').append(this.otherBounds[i].shortReadableName());
+            	}
+            	int length;
+				char[] result = new char[length = buffer.length()];
+				buffer.getChars(0, length, result, 0);
+				return result;	            	
 			default: // SUPER
 			    return CharOperation.concat(WILDCARD_NAME, WILDCARD_SUPER, this.bound.shortReadableName());
         }
@@ -219,7 +424,7 @@
      	// should not be called directly on a wildcard; signature should only be asked on
     	// original methods or type erasures (which cannot denote wildcards at first level)
 		if (this.signature == null) {
-	        switch (this.kind) {
+	        switch (this.boundKind) {
 	            case Wildcard.EXTENDS :
 	                return this.bound.signature();
 				default: // SUPER | UNBOUND
@@ -233,7 +438,7 @@
      * @see org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding#sourceName()
      */
     public char[] sourceName() {
-        switch (this.kind) {
+        switch (this.boundKind) {
             case Wildcard.UNBOUND : 
                 return WILDCARD_NAME;
             case Wildcard.EXTENDS :
@@ -248,13 +453,14 @@
      */
     public ReferenceBinding superclass() {
 		if (this.superclass == null) {
-			TypeBinding superType = this.typeVariable().firstBound;
-			if (this.kind == Wildcard.EXTENDS) {
-				if (this.bound.isClass()) {
-					superType = this.bound;
-				}
+			TypeBinding superType = null;
+			if (this.boundKind == Wildcard.EXTENDS && !this.bound.isInterface()) {
+				superType = this.bound;
+			} else {
+				TypeVariableBinding variable = this.typeVariable();
+				if (variable != null) superType = variable.firstBound;
 			}
-			this.superclass = superType != null && superType.isClass()
+			this.superclass = superType instanceof ReferenceBinding && !superType.isInterface()
 				? (ReferenceBinding) superType
 				: environment.getType(JAVA_LANG_OBJECT);
 		}
@@ -271,13 +477,22 @@
         	} else {
         		this.superInterfaces = NoSuperInterfaces;
         	}
-			if (this.kind == Wildcard.EXTENDS) {
+			if (this.boundKind == Wildcard.EXTENDS) {
 				if (this.bound.isInterface()) {
 					// augment super interfaces with the wildcard bound
 					int length = this.superInterfaces.length;
 					System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[length+1], 1, length);
 					this.superInterfaces[0] = (ReferenceBinding) this.bound; // make bound first
 				}
+				if (this.otherBounds != null) {
+					// augment super interfaces with the wildcard otherBounds (interfaces per construction)
+					int length = this.superInterfaces.length;
+					int otherLength = this.otherBounds.length;
+					System.arraycopy(this.superInterfaces, 0, this.superInterfaces = new ReferenceBinding[length+otherLength], 0, length);
+					for (int i = 0; i < otherLength; i++) {
+						this.superInterfaces[length+i] = (ReferenceBinding) this.otherBounds[i];
+					}
+				}
 			}
         }
         return this.superInterfaces;
@@ -293,18 +508,24 @@
 			affected = true;
 		}
 		if (affected) 
-			initialize(this.genericType, this.bound);
+			initialize(this.genericType, this.bound, this.otherBounds);
 	}
 
 	/**
 	 * @see java.lang.Object#toString()
 	 */
 	public String toString() {
-        switch (this.kind) {
+        switch (this.boundKind) {
             case Wildcard.UNBOUND : 
                 return new String(WILDCARD_NAME);
             case Wildcard.EXTENDS :
-                return new String(CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, this.bound.debugName().toCharArray()));
+            	if (this.otherBounds == null)
+                	return new String(CharOperation.concat(WILDCARD_NAME, WILDCARD_EXTENDS, this.bound.debugName().toCharArray()));
+            	StringBuffer buffer = new StringBuffer(this.bound.debugName());
+            	for (int i = 0, length = this.otherBounds.length; i < length; i++) {
+            		buffer.append('&').append(this.otherBounds[i].debugName());
+            	}
+            	return buffer.toString();
 			default: // SUPER
 			    return new String(CharOperation.concat(WILDCARD_NAME, WILDCARD_SUPER, this.bound.debugName().toCharArray()));
         }        
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index 9b5dd5d..e1a39ff 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -58,6 +58,7 @@
 	// Kind of comment parser
 	public final static int COMPIL_PARSER = 0x00000001;
 	public final static int DOM_PARSER = 0x00000002;
+	public final static int SELECTION_PARSER = 0x00000003;
 	
 	// Parse infos
 	public Scanner scanner;
@@ -71,11 +72,14 @@
 	protected boolean jdk15;
 	
 	// Results
-	protected boolean inherited, deprecated;
+	protected long inheritedPositions;
+	protected boolean deprecated;
 	protected Object returnStatement;
 	
 	// Positions
-	protected int index, endComment, lineEnd;
+	protected int javadocStart, javadocEnd;
+	protected int firstTagPosition;
+	protected int index, lineEnd;
 	protected int tokenPreviousPosition, lastIdentifierEndPosition, starPosition;
 	protected int textStart, memberStart;
 	protected int tagSourceStart, tagSourceEnd;
@@ -83,7 +87,9 @@
 	protected int[] lineEnds;
 	
 	// Flags
-	protected boolean lineStarted = false, inlineTagStarted = false;
+	protected boolean lineStarted = false;
+	protected boolean inlineTagStarted = false;
+	protected boolean abort = false;
 	protected int kind;
 	
 	// Line pointers
@@ -95,6 +101,7 @@
 	protected int identifierLengthPtr;
 	protected int[] identifierLengthStack;
 	protected long[] identifierPositionStack;
+
 	// Ast stack
 	protected static int AstStackIncrement = 10;
 	protected int astPtr;
@@ -119,19 +126,24 @@
 	 * If javadoc checking is enabled, will also construct an Javadoc node, which will be stored into Parser.javadoc
 	 * slot for being consumed later on.
 	 */
-	protected boolean commentParse(int javadocStart, int javadocEnd) {
-
+	protected boolean commentParse() {
+		
 		boolean validComment = true;
 		try {
 			// Init scanner position
-			this.scanner.resetTo(javadocStart, javadocEnd);
-			this.endComment = javadocEnd;
-			this.index = javadocStart;
-			readChar(); // starting '/'
+			this.linePtr = getLineNumber(this.firstTagPosition);
+			int realStart = this.linePtr==1 ? javadocStart : this.scanner.getLineEnd(this.linePtr-1)+1;
+			if (realStart < javadocStart) realStart = javadocStart;
+			this.scanner.resetTo(realStart, javadocEnd);
+			this.index = realStart;
+			if (realStart == javadocStart) {
+				readChar(); // starting '/'
+				readChar(); // first '*'
+			}
 			int previousPosition = this.index;
-			readChar(); // first '*'
-			char nextCharacter= readChar(); // second '*'
-			
+			char nextCharacter = 0;
+			if (realStart == javadocStart) nextCharacter = readChar(); // second '*'
+
 			// Init local variables
 			this.astLengthPtr = -1;
 			this.astPtr = -1;
@@ -140,18 +152,17 @@
 			this.inlineTagStart = -1;
 			this.lineStarted = false;
 			this.returnStatement = null;
-			this.inherited = false;
+			this.inheritedPositions = -1;
 			this.deprecated = false;
-			this.linePtr = getLineNumber(javadocStart);
 			this.lastLinePtr = getLineNumber(javadocEnd);
-			this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.endComment : this.scanner.getLineEnd(this.linePtr);
+			this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.javadocEnd: this.scanner.getLineEnd(this.linePtr) - 1;
 			this.textStart = -1;
 			char previousChar = 0;
 			int invalidTagLineEnd = -1;
 			int invalidInlineTagLineEnd = -1;
 			
 			// Loop on each comment character
-			while (this.index < this.endComment) {
+			characterLoop: while (!abort && this.index < this.javadocEnd) {
 				previousPosition = this.index;
 				previousChar = nextCharacter;
 				
@@ -178,7 +189,7 @@
 					consumeToken();
 				}
 			
-				if (this.index >= this.endComment) {
+				if (this.index >= this.javadocEnd) {
 					break;
 				}
 				
@@ -197,20 +208,20 @@
 								}
 								validComment = false;
 								if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
-									pushText(this.textStart, previousPosition);
+									if (this.kind == DOM_PARSER) pushText(this.textStart, previousPosition);
 								}
 								if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
 							}
 							if (previousChar == '{') {
 								if (this.textStart != -1 && this.textStart < this.inlineTagStart) {
-									pushText(this.textStart, this.inlineTagStart);
+									if (this.kind == DOM_PARSER) pushText(this.textStart, this.inlineTagStart);
 								}
 								this.inlineTagStarted = true;
 								invalidInlineTagLineEnd = this.lineEnd;
 							} else if (this.textStart != -1 && this.textStart < invalidTagLineEnd) {
-								pushText(this.textStart, invalidTagLineEnd);
+								if (this.kind == DOM_PARSER) pushText(this.textStart, invalidTagLineEnd);
 							}
-							this.scanner.resetTo(this.index, this.endComment);
+							this.scanner.resetTo(this.index, this.javadocEnd);
 							this.currentTokenType = -1; // flush token cache at line begin
 							try {
 								if (!parseTag(previousPosition)) {
@@ -228,23 +239,32 @@
 							} catch (InvalidInputException e) {
 								consumeToken();
 							}
+						} else {
+							if (this.kind == COMPIL_PARSER && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+								refreshReturnStatement();
+							}
 						}
 						break;
 					case '\r':
 					case '\n':
 						if (this.lineStarted && this.textStart < previousPosition) {
-							pushText(this.textStart, previousPosition);
+							if (this.kind == DOM_PARSER) pushText(this.textStart, previousPosition);
 						}
 						this.lineStarted = false;
 						// Fix bug 51650
 						this.textStart = -1;
 						break;
 					case '}' :
+						if (this.kind == COMPIL_PARSER && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+							refreshReturnStatement();
+						}
 						if (this.inlineTagStarted) {
-							if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+							if (this.kind == DOM_PARSER) {
+								if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
 								pushText(this.textStart, previousPosition);
+								}
+								refreshInlineTagPosition(previousPosition);
 							}
-							if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
 							this.textStart = this.index;
 							this.inlineTagStarted = false;
 						} else {
@@ -255,6 +275,9 @@
 						this.lineStarted = true;
 						break;
 					case '{' :
+						if (this.kind == COMPIL_PARSER && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+							refreshReturnStatement();
+						}
 						if (this.inlineTagStarted) {
 							this.inlineTagStarted = false;
 							// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
@@ -263,10 +286,12 @@
 								int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
 								this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
 							}
-							if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
-								pushText(this.textStart, previousPosition);
+							if (this.kind == DOM_PARSER) {
+								if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+									pushText(this.textStart, previousPosition);
+								}
+								refreshInlineTagPosition(previousPosition);
 							}
-							if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
 						}
 						if (!this.lineStarted) {
 							this.textStart = previousPosition;
@@ -281,6 +306,9 @@
 						// do nothing for space or '*' characters
 						break;
 					default :
+						if (this.kind == COMPIL_PARSER && this.tagValue == TAG_RETURN_VALUE && this.returnStatement != null) {
+							refreshReturnStatement();
+						}
 						if (!this.lineStarted) {
 							this.textStart = previousPosition;
 						}
@@ -294,16 +322,16 @@
 				this.inlineTagStarted = false;
 				if (this.reportProblems) {
 					int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
-					if (this.index >= this.endComment) end = invalidInlineTagLineEnd;
+					if (this.index >= this.javadocEnd) end = invalidInlineTagLineEnd;
 					this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
 				}
-				if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
-					pushText(this.textStart, previousPosition);
-				}
 				if (this.kind == DOM_PARSER) {
+					if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+						pushText(this.textStart, previousPosition);
+					}
 					refreshInlineTagPosition(previousPosition);
 				}
-			} else if (this.lineStarted && this.textStart < previousPosition) {
+			} else if (this.kind == DOM_PARSER && this.lineStarted && this.textStart < previousPosition) {
 				pushText(this.textStart, previousPosition);
 			}
 			updateDocComment();
@@ -318,7 +346,7 @@
 		updateLineEnd();
 	}
 
-	protected abstract Object createArgumentReference(char[] name, int dim, Object typeRef, long[] dimPos, long argNamePos) throws InvalidInputException;
+	protected abstract Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPos, long argNamePos) throws InvalidInputException;
 	protected abstract Object createFieldReference(Object receiver) throws InvalidInputException;
 	protected abstract Object createMethodReference(Object receiver, List arguments) throws InvalidInputException;
 	protected Object createReturnStatement() { return null; }
@@ -394,6 +422,7 @@
 			Object typeRef;
 			try {
 				typeRef = parseQualifiedName(false);
+				if (this.abort) return null; // May be aborted by specialized parser
 			} catch (InvalidInputException e) {
 				break nextArg;
 			}
@@ -420,10 +449,12 @@
 			}
 			iToken++;
 
-			// Read possible array declaration
+			// Read possible additional type info
 			int dim = 0;
+			boolean isVarargs = false;
 			long[] dimPositions = new long[20]; // assume that there won't be more than 20 dimensions...
 			if (readToken() == TerminalTokens.TokenNameLBRACKET) {
+				// array declaration
 				int dimStart = this.scanner.getCurrentTokenStartPosition();
 				while (readToken() == TerminalTokens.TokenNameLBRACKET) {
 					consumeToken();
@@ -433,6 +464,12 @@
 					consumeToken();
 					dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
 				}
+			} else if (readToken() == TerminalTokens.TokenNameELLIPSIS) {
+				// ellipsis declaration
+				int dimStart = this.scanner.getCurrentTokenStartPosition();
+				dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+				consumeToken();
+				isVarargs = true;
 			}
 
 			// Read argument name
@@ -471,7 +508,8 @@
 			char[] name = argName == null ? new char[0] : argName;
 			if (token == TerminalTokens.TokenNameCOMMA) {
 				// Create new argument
-				Object argument = createArgumentReference(name, dim, typeRef, dimPositions, argNamePos);
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				if (this.abort) return null; // May be aborted by specialized parser
 				arguments.add(argument);
 				consumeToken();
 				iToken++;
@@ -484,7 +522,8 @@
 					return null;
 				}
 				// Create new argument
-				Object argument = createArgumentReference(name, dim, typeRef, dimPositions, argNamePos);
+				Object argument = createArgumentReference(name, dim, isVarargs, typeRef, dimPositions, argNamePos);
+				if (this.abort) return null; // May be aborted by specialized parser
 				arguments.add(argument);
 				consumeToken();
 				return createMethodReference(receiver, arguments);
@@ -980,6 +1019,7 @@
 						if (typeRef == null) {
 							typeRefStartPosition = this.scanner.getCurrentTokenStartPosition();
 							typeRef = parseQualifiedName(true);
+							if (this.abort) return false; // May be aborted by specialized parser
 							break;
 						}
 					default :
@@ -1058,6 +1098,7 @@
 		int start = this.scanner.currentPosition;
 		try {
 			Object typeRef = parseQualifiedName(true);
+			if (this.abort) return false; // May be aborted by specialized parser
 			if (typeRef == null) {
 				if (this.reportProblems)
 					this.sourceParser.problemReporter().javadocMissingThrowsClassName(this.tagSourceStart, this.tagSourceEnd, this.sourceParser.modifiers);
@@ -1171,7 +1212,9 @@
 	/*
 	 * Push a text element in ast node stack
 	 */
-	protected abstract void pushText(int start, int end);
+	protected void pushText(int start, int end) {
+		// do not store text by default
+	}
 
 	/*
 	 * Push a throws type ref in ast node stack.
@@ -1206,7 +1249,7 @@
 	/*
 	 * Read token only if previous was consumed
 	 */
-	private int readToken() throws InvalidInputException {
+	protected int readToken() throws InvalidInputException {
 		if (this.currentTokenType < 0) {
 			this.tokenPreviousPosition = this.scanner.currentPosition;
 			this.currentTokenType = this.scanner.getNextToken();
@@ -1235,6 +1278,13 @@
 		// do nothing by default
 	}
 
+	/*
+	 * Refresh return statement
+	 */
+	protected void refreshReturnStatement() {
+		// do nothing by default
+	}
+
 	public String toString() {
 		StringBuffer buffer = new StringBuffer();
 		int startPos = this.scanner.currentPosition<this.index ? this.scanner.currentPosition : this.index;
@@ -1299,7 +1349,7 @@
 			if (this.linePtr < this.lastLinePtr) {
 				this.lineEnd = this.scanner.getLineEnd(++this.linePtr) - 1;
 			} else {
-				this.lineEnd = this.endComment;
+				this.lineEnd = this.javadocEnd;
 				return;
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index a136baf..e6e3388 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,8 +16,6 @@
 import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
 
 /**
  * Parser specialized for decoding javadoc comments
@@ -32,9 +30,6 @@
 	private int invalidParamReferencesPtr = -1;
 	private ASTNode[] invalidParamReferencesStack;
 
-	// Store current tag stack pointer
-	private int currentAstPtr= -2;
-
 	public JavadocParser(Parser sourceParser) {
 		super(sourceParser);
 		this.checkDocComment = this.sourceParser.options.docCommentSupport;
@@ -48,30 +43,40 @@
 	 * If javadoc checking is enabled, will also construct an Javadoc node, which will be stored into Parser.javadoc
 	 * slot for being consumed later on.
 	 */
-	public boolean checkDeprecation(int javadocStart, int javadocEnd) {
+	public boolean checkDeprecation(int commentPtr) {
 
+		// Store javadoc positions
+		this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr];
+		this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]-1;
+		this.firstTagPosition = this.sourceParser.scanner.commentTagStarts[commentPtr];
+
+		// Init javadoc if necessary
+		if (this.checkDocComment) {
+			this.docComment = new Javadoc(javadocStart, javadocEnd);
+		} else {
+			this.docComment = null;
+		}
+		
+		// If there's no tag in javadoc, return without parsing it
+		if (this.firstTagPosition == 0) {
+			return false;
+		}
+
+		// Parse
 		try {
 			this.source = this.sourceParser.scanner.source;
-			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);
-				commentParse(javadocStart, javadocEnd);
+				commentParse();
 			} else {
-				// Init javadoc if necessary
-				if (this.sourceParser.options.getSeverity(CompilerOptions.MissingJavadocComments) != ProblemSeverities.Ignore) {
-					this.docComment = new Javadoc(javadocStart, javadocEnd);
-				} else {
-					this.docComment = null;
-				}
 				
 				// Parse comment
 				int firstLineNumber = this.sourceParser.scanner.getLineNumber(javadocStart);
 				int lastLineNumber = this.sourceParser.scanner.getLineNumber(javadocEnd);
+				this.index = javadocStart +3;
 	
 				// scan line per line, since tags must be at beginning of lines only
 				nextLine : for (int line = firstLineNumber; line <= lastLineNumber; line++) {
@@ -128,7 +133,7 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createArgumentReference(char[], java.lang.Object, int)
 	 */
-	protected Object createArgumentReference(char[] name, int dim, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
 		try {
 			TypeReference argTypeRef = (TypeReference) typeRef;
 			if (dim > 0) {
@@ -142,7 +147,12 @@
 				}
 			}
 			int argEnd = argTypeRef.sourceEnd;
-			if (dim > 0) argEnd = (int) dimPositions[dim-1];
+			if (dim > 0) {
+				argEnd = (int) dimPositions[dim-1];
+				if (isVarargs) {
+					argTypeRef.bits |= ASTNode.IsVarArgs; // set isVarArgs
+				}
+			}
 			if (argNamePos >= 0) argEnd = (int) argNamePos;
 			return new JavadocArgumentExpression(name, argTypeRef.sourceStart, argEnd, argTypeRef);
 		}
@@ -159,7 +169,7 @@
 			TypeReference typeRef = (TypeReference) receiver;
 			if (typeRef == null) {
 				char[] name = this.sourceParser.compilationUnit.getMainTypeName();
-				typeRef = new ImplicitDocTypeReference(name, this.memberStart);
+				typeRef = new JavadocImplicitTypeReference(name, this.memberStart);
 			}
 			// Create field
 			JavadocFieldReference field = new JavadocFieldReference(this.identifierStack[0], this.identifierPositionStack[0]);
@@ -184,8 +194,20 @@
 			boolean isConstructor = false;
 			if (typeRef == null) {
 				char[] name = this.sourceParser.compilationUnit.getMainTypeName();
+				int ptr = this.sourceParser.astPtr;
+				while (ptr >= 0) {
+					Object node = this.sourceParser.astStack[ptr];
+					if (node instanceof TypeDeclaration) {
+						TypeDeclaration typeDecl = (TypeDeclaration) node;
+						if (typeDecl.bodyEnd == 0) { // type declaration currenly parsed
+							name = typeDecl.name;
+							break;
+						}
+					}
+					ptr--;
+				}
 				isConstructor = CharOperation.equals(this.identifierStack[0], name);
-				typeRef = new ImplicitDocTypeReference(name, this.memberStart);
+				typeRef = new JavadocImplicitTypeReference(name, this.memberStart);
 			} else {
 				char[] name = null;
 				if (typeRef instanceof JavadocSingleTypeReference) {
@@ -204,11 +226,13 @@
 					JavadocAllocationExpression alloc = new JavadocAllocationExpression(this.identifierPositionStack[0]);
 					alloc.type = typeRef;
 					alloc.tagValue = this.tagValue;
+					alloc.sourceEnd = this.scanner.getCurrentTokenEndPosition();
 					return alloc;
 				} else {
 					JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[0], this.identifierPositionStack[0]);
 					msg.receiver = typeRef;
 					msg.tagValue = this.tagValue;
+					msg.sourceEnd = this.scanner.getCurrentTokenEndPosition();
 					return msg;
 				}
 			} else {
@@ -219,17 +243,19 @@
 					alloc.arguments = expressions;
 					alloc.type = typeRef;
 					alloc.tagValue = this.tagValue;
+					alloc.sourceEnd = this.scanner.getCurrentTokenEndPosition();
 					return alloc;
 				} else {
 					JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[0], this.identifierPositionStack[0], expressions);
 					msg.receiver = typeRef;
 					msg.tagValue = this.tagValue;
+					msg.sourceEnd = this.scanner.getCurrentTokenEndPosition();
 					return msg;
 				}
 			}
 		}
 		catch (ClassCastException ex) {
-				throw new InvalidInputException();
+			throw new InvalidInputException();
 		}
 	}
 	/* (non-Javadoc)
@@ -237,8 +263,7 @@
 	 */
 	protected Object createReturnStatement() {
 		return new JavadocReturnStatement(this.scanner.getCurrentTokenStartPosition(),
-					this.scanner.getCurrentTokenEndPosition(),
-					this.scanner.getRawTokenSourceEnd());
+					this.scanner.getCurrentTokenEndPosition());
 	}
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createTypeReference()
@@ -269,7 +294,6 @@
 	protected boolean parseReturn() {
 		if (this.returnStatement == null) {
 			this.returnStatement = createReturnStatement();
-			this.currentAstPtr = this.astPtr;
 			return true;
 		}
 		if (this.sourceParser != null) this.sourceParser.problemReporter().javadocDuplicatedReturnTag(
@@ -278,24 +302,61 @@
 		return false;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseTag(int)
-	 */
 	protected boolean parseTag(int previousPosition) throws InvalidInputException {
 		boolean valid = false;
-
-		// In case of previous return tag, set it to not empty if parsing an inline tag
-		if (this.currentAstPtr != -2 && this.returnStatement != null) {
-			this.currentAstPtr = -2;
-			JavadocReturnStatement javadocReturn = (JavadocReturnStatement) this.returnStatement;
-			javadocReturn.empty = javadocReturn.empty && !this.inlineTagStarted;
-		}
-
+	
 		// Read tag name
 		int token = readTokenAndConsume();
 		this.tagSourceStart = this.scanner.getCurrentTokenStartPosition();
 		this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
-		char[] tag = this.scanner.getCurrentIdentifierSource(); // first token is either an identifier or a keyword
+	
+		// Try to get tag name other than java identifier
+		// (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660)
+		char pc = peekChar();
+		boolean validTag = false;
+		switch (token) {
+			case TerminalTokens.TokenNameIdentifier:
+			case TerminalTokens.TokenNamereturn:
+			case TerminalTokens.TokenNamethrows:
+				validTag= true;
+		}
+		tagNameToken: while (token != TerminalTokens.TokenNameEOF && this.index < this.scanner.eofPosition) {
+			// !, ", #, %, &, ', -, :, <, >, * chars and spaces are not allowed in tag names
+			switch (pc) {
+				case '}':
+				case '*': // break for '*' as this is perhaps the end of comment (bug 65288)
+					break tagNameToken;
+				case '!':
+				case '#':
+				case '%':
+				case '&':
+				case '\'':
+				case '"':
+				case ':':
+				// case '-': allowed in tag names as this character is often used in doclets (bug 68087)
+				case '<':
+				case '>':
+					readChar();
+					this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+					validTag = false;
+					break;
+				default:
+					if (pc == ' ' || Character.isWhitespace(pc)) break tagNameToken;
+					this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+					token = readTokenAndConsume();
+			}
+			pc = peekChar();
+		}
+		if (!validTag) {
+			this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+			if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, this.tagSourceEnd);
+			return false;
+		}
+		int length = this.tagSourceEnd-this.tagSourceStart+1;
+		char[] tag = new char[length];
+		System.arraycopy(this.source, this.tagSourceStart, tag, 0, length);
+		this.index = this.tagSourceEnd+1;
+		this.scanner.currentPosition = this.tagSourceEnd+1;
 
 		// Decide which parse to perform depending on tag name
 		this.tagValue = NO_TAG_VALUE;
@@ -316,7 +377,9 @@
 							// Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
 							// was encountered in comment. But it cannot be the case for COMPILER_PARSER
 							// and so is enough as it is only this parser which signals the missing tag warnings...
-							this.inherited = this.astPtr==-1;
+							if (this.astPtr==-1) {
+								this.inheritedPositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+							}
 							valid = true;
 							this.tagValue = TAG_INHERITDOC_VALUE;
 						}
@@ -505,40 +568,6 @@
 		return true;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushText(int, int)
-	 */
-	protected void pushText(int start, int end) {
-		// In case of previous return tag, verify that text make it not empty
-		if (this.currentAstPtr != -2 && this.returnStatement != null) {
-			int position = this.index;
-			this.index = start;
-			boolean empty = true;
-			boolean star = false;
-			char ch = readChar();
-			// Look for first character other than white or '*'
-			if (Character.isWhitespace(ch) || start>(this.tagSourceEnd+1)) {
-				while (this.index <= end && empty) {
-					if (!star) {
-						empty = Character.isWhitespace(ch) || ch == '*';
-						star = ch == '*';
-					} else if (ch != '*') {
-						empty = false;
-						break;
-					}
-					ch = readChar();
-				}
-			}
-			// Store result in previous return tag
-			((JavadocReturnStatement)this.returnStatement).empty = empty;
-			// Reset position and current ast ptr if we are on a different tag than previous return one
-			this.index = position;
-			if (this.currentAstPtr != this.astPtr) {
-				this.currentAstPtr = -2;
-			}
-		}
-	}
-
 	/*
 	 * Push a throws type ref in ast node stack.
 	 */
@@ -569,12 +598,19 @@
 	}
 
 	/*
+	 * Refresh return statement
+	 */
+	protected void refreshReturnStatement() {
+		((JavadocReturnStatement) this.returnStatement).empty = false;
+	}
+
+	/*
 	 * Fill associated comment fields with ast nodes information stored in stack.
 	 */
 	protected void updateDocComment() {
 		
-		// Set inherited flag
-		this.docComment.inherited = this.inherited;
+		// Set inherited positions
+		this.docComment.inheritedPositions = this.inheritedPositions;
 
 		// Set return node if present
 		if (this.returnStatement != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSLine.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSLine.java
index 99af1e3..99db505 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSLine.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/NLSLine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index cedccfe..626e32a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196
@@ -31,11 +31,13 @@
 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser;
 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
 public class Parser implements  ParserBasicInformation, TerminalTokens, CompilerModifiers, OperatorIds, TypeIds {
@@ -183,7 +185,7 @@
 	public JavadocParser javadocParser;
 	// used for recovery
 	protected int lastJavadocEnd;
-
+	
 	static {
 		try{
 			initTables();
@@ -428,7 +430,7 @@
 	try {
 		contents = Util.getFileCharContent(new File(dataFilename), null);
 	} catch (IOException ex) {
-		System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
+		System.out.println(Messages.parser_incorrectPath); 
 		return;
 	}
 	java.util.StringTokenizer st = 
@@ -469,7 +471,7 @@
 	try {
 		contents = Util.getFileCharContent(new File(dataFilename2), null);
 	} catch (IOException ex) {
-		System.out.println(Util.bind("parser.incorrectPath")); //$NON-NLS-1$
+		System.out.println(Messages.parser_incorrectPath); 
 		return;
 	}
 	st = new java.util.StringTokenizer(new String(contents), "\t\n\r=#");  //$NON-NLS-1$
@@ -482,7 +484,7 @@
 	buildFileForCompliance(prefix + (++i) + ".rsc", newRhs.length, tokens);//$NON-NLS-1$
 	buildFileForReadableName(READABLE_NAMES_FILE+".properties", newLhs, newNonTerminalIndex, newName, tokens);//$NON-NLS-1$
 	
-	System.out.println(Util.bind("parser.moveFiles")); //$NON-NLS-1$
+	System.out.println(Messages.parser_moveFiles); 
 }
 public static int in_symbol(int state) {
 	return in_symb[original_state(state)];
@@ -540,7 +542,7 @@
 
 	InputStream stream = Parser.class.getResourceAsStream(filename);
 	if (stream == null) {
-		throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
+		throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename)); 
 	}
 	byte[] bytes = null;
 	try {
@@ -601,7 +603,7 @@
 
 	InputStream stream = Parser.class.getResourceAsStream(filename);
 	if (stream == null) {
-		throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
+		throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename)); 
 	}
 	byte[] bytes = null;
 	try {
@@ -618,7 +620,7 @@
 	//minimal integrity check (even size expected)
 	int length = bytes.length;
 	if (length % 2 != 0)
-		throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$
+		throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename)); 
 
 	// convert bytes into chars
 	char[] chars = new char[length / 2];
@@ -638,7 +640,7 @@
 
 	InputStream stream = Parser.class.getResourceAsStream(filename);
 	if (stream == null) {
-		throw new java.io.IOException(Util.bind("parser.missingFile",filename)); //$NON-NLS-1$
+		throw new java.io.IOException(Messages.bind(Messages.parser_missingFile, filename)); 
 	}
 	byte[] bytes = null;
 	try {
@@ -655,7 +657,7 @@
 	//minimal integrity check (even size expected)
 	int length = bytes.length;
 	if (length % 8 != 0)
-		throw new java.io.IOException(Util.bind("parser.corruptedFile",filename)); //$NON-NLS-1$
+		throw new java.io.IOException(Messages.bind(Messages.parser_corruptedFile, filename)); 
 
 	// convert bytes into longs
 	long[] longs = new long[length / 8];
@@ -879,7 +881,7 @@
 			int commentEnd = this.scanner.commentStops[lastComment] - 1; //stop is one over,
 			// do not report problem before last parsed comment while recovering code...
 			this.javadocParser.reportProblems = this.currentElement == null || commentEnd > this.lastJavadocEnd;
-			if (this.javadocParser.checkDeprecation(this.scanner.commentStarts[lastComment], commentEnd)) {
+			if (this.javadocParser.checkDeprecation(lastComment)) {
 				checkAndSetModifiers(AccDeprecated);
 			}
 			this.javadoc = this.javadocParser.docComment;	// null if check javadoc is not activated
@@ -1028,7 +1030,11 @@
 	this.restartRecovery = true; // request to restart from here on
 }
 protected void consumeAnnotationAsModifier() {
-	// nothing to do
+	Expression expression = this.expressionStack[this.expressionPtr];
+	int sourceStart = expression.sourceStart;
+	if (this.modifiersSourceStart < 0) {
+		this.modifiersSourceStart = sourceStart;
+	}
 }
 protected void consumeAnnotationName() {
 	// nothing to do
@@ -1154,6 +1160,7 @@
 protected void consumeArguments() {
 	// Arguments ::= '(' ArgumentListopt ')' 
 	// nothing to do, the expression stack is already updated
+	pushOnIntStack(rParenPos);
 }
 protected void consumeArrayAccess(boolean unspecifiedReference) {
 	// ArrayAccess ::= Name '[' Expression ']' ==> true
@@ -2363,6 +2370,8 @@
 }
 protected void consumeEmptyArguments() {
 	// Argumentsopt ::= $empty
+	final FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
+	pushOnIntStack(fieldDeclaration.sourceEnd);
 	pushOnExpressionStackLengthStack(0);
 }
 protected void consumeEmptyArrayInitializer() {
@@ -2574,52 +2583,17 @@
 		this.lastIgnoredToken = -1;
 	}	
 }
-protected void consumeEnterAnonymousClassBodySimpleName() {
-	// EnterAnonymousClassBody ::= $empty
-	pushOnGenericsLengthStack(0);
-	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
-	TypeReference typeReference = getTypeReference(0);
-
-	TypeDeclaration anonymousType = new TypeDeclaration(this.compilationUnit.compilationResult); 
-	anonymousType.name = TypeDeclaration.ANONYMOUS_EMPTY_NAME;
-	anonymousType.bits |= ASTNode.AnonymousAndLocalMask;
-	QualifiedAllocationExpression alloc = new QualifiedAllocationExpression(anonymousType); 
-	markEnclosingMemberWithLocalType();
-	pushOnAstStack(anonymousType);
-
-	alloc.sourceEnd = this.rParenPos; //the position has been stored explicitly
-	int argumentLength;
-	if ((argumentLength = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
-		this.expressionPtr -= argumentLength;
-		System.arraycopy(
-			this.expressionStack, 
-			this.expressionPtr + 1, 
-			alloc.arguments = new Expression[argumentLength], 
-			0, 
-			argumentLength); 
-	}
-	alloc.type = typeReference;
-
-	anonymousType.sourceEnd = alloc.sourceEnd;
-	//position at the type while it impacts the anonymous declaration
-	anonymousType.sourceStart = anonymousType.declarationSourceStart = alloc.type.sourceStart;
-	alloc.sourceStart = this.intStack[this.intPtr--];
-	pushOnExpressionStack(alloc);
-
-	anonymousType.bodyStart = this.scanner.currentPosition;	
-	this.listLength = 0; // will be updated when reading super-interfaces
-	// recovery
-	if (this.currentElement != null){ 
-		this.lastCheckPoint = anonymousType.bodyStart;		
-		this.currentElement = this.currentElement.add(anonymousType, 0);
-		this.currentToken = 0; // opening brace already taken into account
-		this.lastIgnoredToken = -1;
-	}	
-}
 protected void consumeEnterCompilationUnit() {
 	// EnterCompilationUnit ::= $empty
 	// do nothing by default
 }
+protected void consumeEnterMemberValue() {
+	// EnterMemberValue ::= $empty
+	if(this.currentElement != null && this.currentToken == TokenNameLBRACE) {
+		this.ignoreNextOpeningBrace = true;
+		this.currentElement.bracketBalance++; 
+	}
+}
 protected void consumeEnterVariable() {
 	// EnterVariable ::= $empty
 	// do nothing by default
@@ -2699,19 +2673,7 @@
 		declaration.type = type;
 	} else {
 		int dimension = typeDim + extendedDimension;
-		//on the this.identifierLengthStack there is the information about the type....
-		int baseType;
-		if ((baseType = this.identifierLengthStack[this.identifierLengthPtr + 1]) < 0) {
-			//it was a baseType
-			int typeSourceStart = type.sourceStart;
-			int typeSourceEnd = type.sourceEnd;
-			type = TypeReference.baseTypeReference(-baseType, dimension);
-			type.sourceStart = typeSourceStart;
-			type.sourceEnd = typeSourceEnd;
-			declaration.type = type;
-		} else {
-			declaration.type = this.copyDims(type, dimension);
-		}
+		declaration.type = this.copyDims(type, dimension);
 	}
 	this.variablesCounter[this.nestedType]++;
 	pushOnAstStack(declaration);
@@ -2757,9 +2719,10 @@
 		}
 	}
    long namePosition = this.identifierPositionStack[this.identifierPtr];
-   char[] constantName = this.identifierStack[this.identifierPtr--];
+   char[] constantName = this.identifierStack[this.identifierPtr];
    final int sourceEnd = (int) namePosition;
    FieldDeclaration enumConstant = createFieldDeclaration(constantName, (int) (namePosition >>> 32), sourceEnd);
+   this.identifierPtr--;
    this.identifierLengthPtr--;
    enumConstant.modifiersSourceStart = this.intStack[this.intPtr--];
    enumConstant.modifiers = this.intStack[this.intPtr--];
@@ -2860,15 +2823,10 @@
 }
 protected void consumeEnumConstantNoClassBody() {
 	// set declarationEnd and declarationSourceEnd
+	int endOfEnumConstant = intStack[intPtr--];
 	final FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
-	int declarationEnd = fieldDeclaration.sourceEnd;
-	if (declarationEnd > rParenPos) {
-		fieldDeclaration.declarationEnd = declarationEnd;
-		fieldDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(declarationEnd);
-	} else {
-		fieldDeclaration.declarationEnd = rParenPos;
-		fieldDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(rParenPos);
-	}
+	fieldDeclaration.declarationEnd = endOfEnumConstant;
+	fieldDeclaration.declarationSourceEnd = endOfEnumConstant;
 }
 protected void consumeEnumConstants() {
 	concatNodeLists();
@@ -2882,6 +2840,7 @@
    final FieldDeclaration fieldDeclaration = ((FieldDeclaration) this.astStack[this.astPtr]);
    fieldDeclaration.declarationEnd = this.endStatementPosition;
    fieldDeclaration.declarationSourceEnd = anonymousType.declarationSourceEnd;
+   intPtr --; // remove end position of the arguments
 }
 protected void consumeEnumDeclaration() {
 	// EnumDeclaration ::= EnumHeader ClassHeaderImplementsopt EnumBody
@@ -3036,6 +2995,10 @@
 			this.expressionStack[this.expressionPtr],
 			op);
 }
+protected void consumeExitMemberValue() {
+	// ExitMemberValue ::= $empty
+	// do nothing by default
+}
 protected void consumeExitTryBlock() {
 	//ExitTryBlock ::= $empty
 	if(this.currentElement != null) {
@@ -3260,7 +3223,7 @@
 	final int typeDimensions = firstDimensions + extendedDimensions;
 	TypeReference type = getTypeReference(typeDimensions);
 	if (isVarArgs) {
-		type = type.copyDims(typeDimensions + 1);
+		type = copyDims(type, typeDimensions + 1);
 		if (extendedDimensions == 0) {
 			type.sourceEnd = endOfEllipsis;
 		}
@@ -3532,6 +3495,14 @@
 	// InternalCompilationUnit ::= PackageDeclaration
 	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
 	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+	if (this.compilationUnit.isPackageInfo()) {
+		this.compilationUnit.types = new TypeDeclaration[1];
+		// create a fake interface declaration
+		TypeDeclaration declaration = new TypeDeclaration(compilationUnit.compilationResult);
+		declaration.name = TypeConstants.PACKAGE_INFO_NAME;
+		declaration.modifiers = AccDefault | AccInterface;
+		this.compilationUnit.types[0] = declaration;
+	}
 }
 protected void consumeInternalCompilationUnitWithTypes() {
 	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
@@ -3541,10 +3512,31 @@
 	// consume type declarations
 	int length;
 	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
-		this.astPtr -= length;
-		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types = new TypeDeclaration[length], 0, length);
+		if (this.compilationUnit.isPackageInfo()) {
+			this.compilationUnit.types = new TypeDeclaration[length + 1];
+			this.astPtr -= length;
+			System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 1, length);
+			// create a fake interface declaration
+			TypeDeclaration declaration = new TypeDeclaration(compilationUnit.compilationResult);
+			declaration.name = TypeConstants.PACKAGE_INFO_NAME;
+			declaration.modifiers = AccDefault | AccInterface;
+			this.compilationUnit.types[0] = declaration;
+		} else {
+			this.compilationUnit.types = new TypeDeclaration[length];
+			this.astPtr -= length;
+			System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+		}
 	}
 }
+protected void consumeInvalidAnnotationTypeDeclaration() {
+	// BlockStatement ::= AnnotationTypeDeclaration
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	problemReporter().illegalLocalTypeDeclaration(typeDecl);
+	// remove the ast node created in interface header
+	this.astPtr--;
+	pushOnAstLengthStack(-1);
+	concatNodeLists();
+}
 protected void consumeInvalidConstructorDeclaration() {
 	// ConstructorDeclaration ::= ConstructorHeader ';'
 	// now we know that the top of stack is a constructorDeclaration
@@ -3556,6 +3548,89 @@
 	
 	cd.modifiers |= AccSemicolonBody; // remember semi-colon body
 }
+protected void consumeInvalidConstructorDeclaration(boolean hasBody) {
+	// InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
+	// InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
+
+	/*
+	this.astStack : modifiers arguments throws statements
+	this.identifierStack : name
+	 ==>
+	this.astStack : MethodDeclaration
+	this.identifierStack :
+	*/
+	if (hasBody) {
+		// pop the position of the {  (body of the method) pushed in block decl
+		this.intPtr--;
+	}
+
+	//statements
+	if (hasBody) {
+		this.realBlockPtr--;
+	}
+
+	int length;
+	if (hasBody && ((length = this.astLengthStack[this.astLengthPtr--]) != 0)) {
+		this.astPtr -= length;
+	}
+	ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) this.astStack[this.astPtr];
+	constructorDeclaration.bodyEnd = this.endStatementPosition;
+	constructorDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+	if (!hasBody) {
+		constructorDeclaration.modifiers |= AccSemicolonBody;
+	}
+}
+protected void consumeInvalidInterfaceDeclaration() {
+	// BlockStatement ::= InvalidInterfaceDeclaration
+	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	problemReporter().illegalLocalTypeDeclaration(typeDecl);
+	// remove the ast node created in interface header
+	this.astPtr--;
+	pushOnAstLengthStack(-1);
+	concatNodeLists();
+}
+protected void consumeInvalidEnumDeclaration() {
+	// BlockStatement ::= EnumDeclaration
+	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+	problemReporter().illegalLocalTypeDeclaration(typeDecl);
+	// remove the ast node created in interface header
+	this.astPtr--;
+	pushOnAstLengthStack(-1);
+	concatNodeLists();
+}
+protected void consumeInvalidMethodDeclaration() {
+	// InterfaceMemberDeclaration ::= InvalidMethodDeclaration
+
+	/*
+	this.astStack : modifiers arguments throws statements
+	this.identifierStack : type name
+	this.intStack : dim dim dim
+	 ==>
+	this.astStack : MethodDeclaration
+	this.identifierStack :
+	this.intStack : 
+	*/
+
+	// pop the position of the {  (body of the method) pushed in block decl
+	this.intPtr--;
+	// retrieve end position of method declarator
+
+	//statements
+	this.realBlockPtr--;
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.astPtr -= length;
+	}
+
+	//watch for } that could be given as a unicode ! ( u007D is '}' )
+	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
+	md.bodyEnd = this.endPosition;
+	md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
+
+	// report the problem and continue the parsing - narrowing the problem onto the method
+	problemReporter().abstractMethodNeedingNoBody(md);
+}
 protected void consumeLeftParen() {
 	// PushLPAREN ::= '('
 	pushOnIntStack(this.lParenPos);
@@ -3607,32 +3682,8 @@
 protected void consumeMarkerAnnotation() {
 	// MarkerAnnotation ::= '@' Name
 	MarkerAnnotation markerAnnotation = null;
-	int length = this.identifierLengthStack[this.identifierLengthPtr--];
-	TypeReference typeReference;
-	if (length == 1) {
-		typeReference = new SingleTypeReference(
-				this.identifierStack[this.identifierPtr], 
-				this.identifierPositionStack[this.identifierPtr--]);
-	} else {
-		char[][] tokens = new char[length][];
-		this.identifierPtr -= length;
-		long[] positions = new long[length];
-		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
-		System.arraycopy(
-			this.identifierPositionStack, 
-			this.identifierPtr + 1, 
-			positions, 
-			0, 
-			length);
-		typeReference = new QualifiedTypeReference(tokens, positions);
-	}
+	TypeReference typeReference = this.getAnnotationType();
 	markerAnnotation = new MarkerAnnotation(typeReference, this.intStack[this.intPtr--]);
-	int sourceStart = markerAnnotation.sourceStart;
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
 	markerAnnotation.declarationSourceEnd = markerAnnotation.sourceEnd;
 	pushOnExpressionStack(markerAnnotation);
 	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
@@ -3794,18 +3845,7 @@
 		TypeReference returnType = md.returnType;
 		md.sourceEnd = this.endPosition;
 		int dims = returnType.dimensions() + extendedDims;
-		int baseType;
-		if ((baseType = this.identifierLengthStack[this.identifierLengthPtr + 1]) < 0) {
-			//it was a baseType
-			int sourceStart = returnType.sourceStart;
-			int sourceEnd =  returnType.sourceEnd;
-			returnType = TypeReference.baseTypeReference(-baseType, dims);
-			returnType.sourceStart = sourceStart;
-			returnType.sourceEnd = sourceEnd;
-			md.returnType = returnType;
-		} else {
-			md.returnType = this.copyDims(md.returnType, dims);
-		}
+		md.returnType = this.copyDims(returnType, dims);
 		if (this.currentToken == TokenNameLBRACE){ 
 			md.bodyStart = this.endPosition + 1;
 		}
@@ -4136,26 +4176,9 @@
 protected void consumeNormalAnnotation() {
 	// NormalAnnotation ::= '@' Name '(' MemberValuePairsopt ')'
 	NormalAnnotation normalAnnotation = null;
-	int length = this.identifierLengthStack[this.identifierLengthPtr--];
-	TypeReference typeReference;
-	if (length == 1) {
-		typeReference = new SingleTypeReference(
-				this.identifierStack[this.identifierPtr], 
-				this.identifierPositionStack[this.identifierPtr--]);
-	} else {
-		char[][] tokens = new char[length][];
-		this.identifierPtr -= length;
-		long[] positions = new long[length];
-		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
-		System.arraycopy(
-			this.identifierPositionStack, 
-			this.identifierPtr + 1, 
-			positions, 
-			0, 
-			length);
-		typeReference = new QualifiedTypeReference(tokens, positions);
-	}
+	TypeReference typeReference = this.getAnnotationType();
 	normalAnnotation = new NormalAnnotation(typeReference, this.intStack[this.intPtr--]);
+	int length;
 	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
 		System.arraycopy(
 			this.astStack, 
@@ -4164,12 +4187,6 @@
 			0, 
 			length); 
 	}
-	int sourceStart = normalAnnotation.sourceStart;
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
 	normalAnnotation.declarationSourceEnd = this.rParenPos;
 	pushOnExpressionStack(normalAnnotation);
 	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
@@ -4212,6 +4229,9 @@
 	}
 	this.realBlockStack[this.realBlockPtr] = 0;
 }
+protected void consumePackageComment() {
+	// do nothing
+}
 protected void consumePackageDeclaration() {
 	// PackageDeclaration ::= 'package' Name ';'
 	/* build an ImportRef build from the last name 
@@ -4608,269 +4628,273 @@
 		     consumePackageDeclarationNameWithModifiers();  
 			break;
  
-    case 93 : if (DEBUG) { System.out.println("PackageDeclarationName ::= package Name"); }  //$NON-NLS-1$
+    case 93 : if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name"); }  //$NON-NLS-1$
 		     consumePackageDeclarationName();  
 			break;
  
-    case 98 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); }  //$NON-NLS-1$
+    case 94 : if (DEBUG) { System.out.println("PackageComment ::="); }  //$NON-NLS-1$
+		     consumePackageComment();  
+			break;
+ 
+    case 99 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 99 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import Name"); }  //$NON-NLS-1$
+    case 100 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import Name"); }  //$NON-NLS-1$
 		    consumeSingleTypeImportDeclarationName();  
 			break;
  
-    case 100 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
+    case 101 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 101 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); }  //$NON-NLS-1$
+    case 102 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); }  //$NON-NLS-1$
 		    consumeTypeImportOnDemandDeclarationName();  
 			break;
  
-     case 104 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+     case 105 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyTypeDeclaration();  
 			break;
  
-    case 108 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); }  //$NON-NLS-1$
+    case 109 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); }  //$NON-NLS-1$
 		    consumeModifiers2();  
 			break;
  
-    case 120 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); }  //$NON-NLS-1$
+    case 121 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); }  //$NON-NLS-1$
 		    consumeAnnotationAsModifier();  
 			break;
  
-    case 121 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); }  //$NON-NLS-1$
+    case 122 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); }  //$NON-NLS-1$
 		    consumeClassDeclaration();  
 			break;
  
-    case 122 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); }  //$NON-NLS-1$
+    case 123 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); }  //$NON-NLS-1$
 		    consumeClassHeader();  
 			break;
  
-    case 123 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); }  //$NON-NLS-1$
+    case 124 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); }  //$NON-NLS-1$
 		    consumeTypeHeaderNameWithTypeParameters();  
 			break;
  
-    case 125 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); }  //$NON-NLS-1$
+    case 126 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); }  //$NON-NLS-1$
 		    consumeClassHeaderName1();  
 			break;
  
-    case 126 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); }  //$NON-NLS-1$
+    case 127 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); }  //$NON-NLS-1$
 		    consumeClassHeaderExtends();  
 			break;
  
-    case 127 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); }  //$NON-NLS-1$
+    case 128 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); }  //$NON-NLS-1$
 		    consumeClassHeaderImplements();  
 			break;
  
-    case 129 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); }  //$NON-NLS-1$
+    case 130 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); }  //$NON-NLS-1$
 		    consumeInterfaceTypeList();  
 			break;
  
-    case 130 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
+    case 131 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
 		    consumeInterfaceType();  
 			break;
  
-    case 133 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); }  //$NON-NLS-1$
+    case 134 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclarations();  
 			break;
  
-    case 137 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block"); }  //$NON-NLS-1$
+    case 138 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod Block"); }  //$NON-NLS-1$
 		    consumeClassBodyDeclaration();  
 			break;
  
-    case 138 : if (DEBUG) { System.out.println("Diet ::="); }  //$NON-NLS-1$
+    case 139 : if (DEBUG) { System.out.println("Diet ::="); }  //$NON-NLS-1$
 		    consumeDiet();  
 			break;
 
-    case 139 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod Block"); }  //$NON-NLS-1$
+    case 140 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod Block"); }  //$NON-NLS-1$
 		    consumeClassBodyDeclaration();  
 			break;
  
-    case 146 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 147 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyClassMemberDeclaration();  
 			break;
 
-    case 149 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 150 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeFieldDeclaration();  
 			break;
  
-    case 151 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); }  //$NON-NLS-1$
+    case 152 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); }  //$NON-NLS-1$
 		    consumeVariableDeclarators();  
 			break;
  
-    case 154 : if (DEBUG) { System.out.println("EnterVariable ::="); }  //$NON-NLS-1$
+    case 155 : if (DEBUG) { System.out.println("EnterVariable ::="); }  //$NON-NLS-1$
 		    consumeEnterVariable();  
 			break;
  
-    case 155 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); }  //$NON-NLS-1$
+    case 156 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); }  //$NON-NLS-1$
 		    consumeExitVariableWithInitialization();  
 			break;
  
-    case 156 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); }  //$NON-NLS-1$
+    case 157 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); }  //$NON-NLS-1$
 		    consumeExitVariableWithoutInitialization();  
 			break;
  
-    case 157 : if (DEBUG) { System.out.println("ForceNoDiet ::="); }  //$NON-NLS-1$
+    case 158 : if (DEBUG) { System.out.println("ForceNoDiet ::="); }  //$NON-NLS-1$
 		    consumeForceNoDiet();  
 			break;
  
-    case 158 : if (DEBUG) { System.out.println("RestoreDiet ::="); }  //$NON-NLS-1$
+    case 159 : if (DEBUG) { System.out.println("RestoreDiet ::="); }  //$NON-NLS-1$
 		    consumeRestoreDiet();  
 			break;
  
-    case 163 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
+    case 164 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
 		    // set to true to consume a method with a body
   consumeMethodDeclaration(true);   
 			break;
  
-    case 164 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); }  //$NON-NLS-1$
+    case 165 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); }  //$NON-NLS-1$
 		    // set to false to consume a method without body
   consumeMethodDeclaration(false);  
 			break;
  
-    case 165 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); }  //$NON-NLS-1$
+    case 166 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); }  //$NON-NLS-1$
 		    consumeMethodHeader();  
 			break;
  
-    case 166 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); }  //$NON-NLS-1$
+    case 167 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); }  //$NON-NLS-1$
 		    consumeMethodHeaderNameWithTypeParameters(false);  
 			break;
  
-    case 167 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); }  //$NON-NLS-1$
+    case 168 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); }  //$NON-NLS-1$
 		    consumeMethodHeaderName(false);  
 			break;
  
-    case 168 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); }  //$NON-NLS-1$
+    case 169 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); }  //$NON-NLS-1$
 		    consumeMethodHeaderRightParen();  
 			break;
  
-    case 169 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); }  //$NON-NLS-1$
+    case 170 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); }  //$NON-NLS-1$
 		    consumeMethodHeaderExtendedDims();  
 			break;
  
-    case 170 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); }  //$NON-NLS-1$
+    case 171 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); }  //$NON-NLS-1$
 		    consumeMethodHeaderThrowsClause();  
 			break;
  
-    case 171 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
+    case 172 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
 		    consumeConstructorHeader();  
 			break;
  
-    case 172 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); }  //$NON-NLS-1$
+    case 173 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); }  //$NON-NLS-1$
 		    consumeConstructorHeaderNameWithTypeParameters();  
 			break;
  
-    case 173 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); }  //$NON-NLS-1$
+    case 174 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); }  //$NON-NLS-1$
 		    consumeConstructorHeaderName();  
 			break;
  
-    case 175 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); }  //$NON-NLS-1$
+    case 176 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); }  //$NON-NLS-1$
 		    consumeFormalParameterList();  
 			break;
  
-    case 176 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 177 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeFormalParameter(false);  
 			break;
  
-    case 177 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS..."); }  //$NON-NLS-1$
+    case 178 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS..."); }  //$NON-NLS-1$
 		    consumeFormalParameter(true);  
 			break;
  
-    case 179 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); }  //$NON-NLS-1$
+    case 180 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); }  //$NON-NLS-1$
 		    consumeClassTypeList();  
 			break;
  
-    case 180 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); }  //$NON-NLS-1$
+    case 181 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); }  //$NON-NLS-1$
 		    consumeClassTypeElt();  
 			break;
  
-    case 181 : if (DEBUG) { System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt..."); }  //$NON-NLS-1$
+    case 182 : if (DEBUG) { System.out.println("MethodBody ::= NestedMethod LBRACE BlockStatementsopt..."); }  //$NON-NLS-1$
 		    consumeMethodBody();  
 			break;
  
-    case 182 : if (DEBUG) { System.out.println("NestedMethod ::="); }  //$NON-NLS-1$
+    case 183 : if (DEBUG) { System.out.println("NestedMethod ::="); }  //$NON-NLS-1$
 		    consumeNestedMethod();  
 			break;
  
-    case 183 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); }  //$NON-NLS-1$
+    case 184 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); }  //$NON-NLS-1$
 		    consumeStaticInitializer();  
 			break;
 
-    case 184 : if (DEBUG) { System.out.println("StaticOnly ::= static"); }  //$NON-NLS-1$
+    case 185 : if (DEBUG) { System.out.println("StaticOnly ::= static"); }  //$NON-NLS-1$
 		    consumeStaticOnly();  
 			break;
  
-    case 185 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); }  //$NON-NLS-1$
+    case 186 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); }  //$NON-NLS-1$
 		    consumeConstructorDeclaration() ;  
 			break;
  
-    case 186 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); }  //$NON-NLS-1$
+    case 187 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); }  //$NON-NLS-1$
 		    consumeInvalidConstructorDeclaration() ;  
 			break;
  
-    case 187 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); }  //$NON-NLS-1$
+    case 188 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(0, THIS_CALL);  
 			break;
  
-    case 188 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); }  //$NON-NLS-1$
+    case 189 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(0,THIS_CALL);  
 			break;
  
-    case 189 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); }  //$NON-NLS-1$
+    case 190 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(0,SUPER_CALL);  
 			break;
  
-    case 190 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 191 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(0,SUPER_CALL);  
 			break;
  
-    case 191 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); }  //$NON-NLS-1$
+    case 192 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(1, SUPER_CALL);  
 			break;
  
-    case 192 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
+    case 193 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL);  
 			break;
  
-    case 193 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); }  //$NON-NLS-1$
+    case 194 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(2, SUPER_CALL);  
 			break;
  
-    case 194 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
+    case 195 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL);  
 			break;
  
-    case 195 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); }  //$NON-NLS-1$
+    case 196 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(1, THIS_CALL);  
 			break;
  
-    case 196 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
+    case 197 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL);  
 			break;
  
-    case 197 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); }  //$NON-NLS-1$
+    case 198 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(2, THIS_CALL);  
 			break;
  
-    case 198 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
+    case 199 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL);  
 			break;
  
-    case 199 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); }  //$NON-NLS-1$
+    case 200 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); }  //$NON-NLS-1$
 		    consumeInterfaceDeclaration();  
 			break;
  
-    case 200 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); }  //$NON-NLS-1$
+    case 201 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); }  //$NON-NLS-1$
 		    consumeInterfaceHeader();  
 			break;
  
-    case 201 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); }  //$NON-NLS-1$
+    case 202 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); }  //$NON-NLS-1$
 		    consumeTypeHeaderNameWithTypeParameters();  
 			break;
  
-    case 203 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); }  //$NON-NLS-1$
+    case 204 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); }  //$NON-NLS-1$
 		    consumeInterfaceHeaderName1();  
 			break;
  
@@ -4886,1194 +4910,1202 @@
 		    consumeEmptyInterfaceMemberDeclaration();  
 			break;
  
-    case 212 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= InvalidMethodDeclaration"); }  //$NON-NLS-1$
-		    ignoreMethodBody();  
+    case 211 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
+		    consumeInvalidMethodDeclaration();  
+			break;
+ 
+    case 212 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
+		    consumeInvalidConstructorDeclaration(true);   
 			break;
  
     case 213 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
-		    ignoreInvalidConstructorDeclaration(true);   
+		    consumeInvalidConstructorDeclaration(false);   
 			break;
  
-    case 214 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
-		    ignoreInvalidConstructorDeclaration(false);   
-			break;
- 
-    case 222 : if (DEBUG) { System.out.println("PushLeftBrace ::="); }  //$NON-NLS-1$
+    case 221 : if (DEBUG) { System.out.println("PushLeftBrace ::="); }  //$NON-NLS-1$
 		    consumePushLeftBrace();  
 			break;
  
-    case 223 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); }  //$NON-NLS-1$
+    case 222 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); }  //$NON-NLS-1$
 		    consumeEmptyArrayInitializer();  
 			break;
  
+    case 223 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
+		    consumeArrayInitializer();  
+			break;
+ 
     case 224 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
 		    consumeArrayInitializer();  
 			break;
  
-    case 225 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
-		    consumeArrayInitializer();  
-			break;
- 
-    case 227 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); }  //$NON-NLS-1$
+    case 226 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); }  //$NON-NLS-1$
 		    consumeVariableInitializers();  
 			break;
  
-    case 228 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); }  //$NON-NLS-1$
+    case 227 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); }  //$NON-NLS-1$
 		    consumeBlock();  
 			break;
  
-    case 229 : if (DEBUG) { System.out.println("OpenBlock ::="); }  //$NON-NLS-1$
+    case 228 : if (DEBUG) { System.out.println("OpenBlock ::="); }  //$NON-NLS-1$
 		    consumeOpenBlock() ;  
 			break;
  
-    case 231 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); }  //$NON-NLS-1$
+    case 230 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); }  //$NON-NLS-1$
 		    consumeBlockStatements() ;  
 			break;
  
-    case 235 : if (DEBUG) { System.out.println("BlockStatement ::= InvalidInterfaceDeclaration"); }  //$NON-NLS-1$
-		    ignoreInterfaceDeclaration();  
+    case 234 : if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration"); }  //$NON-NLS-1$
+		    consumeInvalidInterfaceDeclaration();  
 			break;
  
-    case 236 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); }  //$NON-NLS-1$
+    case 235 : if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration"); }  //$NON-NLS-1$
+		    consumeInvalidAnnotationTypeDeclaration();  
+			break;
+ 
+    case 236 : if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration"); }  //$NON-NLS-1$
+		    consumeInvalidEnumDeclaration();  
+			break;
+ 
+    case 237 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); }  //$NON-NLS-1$
 		    consumeLocalVariableDeclarationStatement();  
 			break;
  
-    case 237 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); }  //$NON-NLS-1$
+    case 238 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); }  //$NON-NLS-1$
 		    consumeLocalVariableDeclaration();  
 			break;
  
-    case 238 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); }  //$NON-NLS-1$
+    case 239 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); }  //$NON-NLS-1$
 		    consumeLocalVariableDeclaration();  
 			break;
  
-    case 239 : if (DEBUG) { System.out.println("PushModifiers ::="); }  //$NON-NLS-1$
+    case 240 : if (DEBUG) { System.out.println("PushModifiers ::="); }  //$NON-NLS-1$
 		    consumePushModifiers();  
 			break;
  
-    case 240 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); }  //$NON-NLS-1$
+    case 241 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); }  //$NON-NLS-1$
 		    consumePushModifiersForHeader();  
 			break;
  
-    case 241 : if (DEBUG) { System.out.println("PushRealModifiers ::="); }  //$NON-NLS-1$
+    case 242 : if (DEBUG) { System.out.println("PushRealModifiers ::="); }  //$NON-NLS-1$
 		    consumePushRealModifiers();  
 			break;
  
-    case 267 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 268 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyStatement();  
 			break;
  
-    case 268 : if (DEBUG) { System.out.println("LabeledStatement ::= Identifier COLON Statement"); }  //$NON-NLS-1$
+    case 269 : if (DEBUG) { System.out.println("LabeledStatement ::= Identifier COLON Statement"); }  //$NON-NLS-1$
 		    consumeStatementLabel() ;  
 			break;
  
-    case 269 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Identifier COLON..."); }  //$NON-NLS-1$
+    case 270 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Identifier COLON..."); }  //$NON-NLS-1$
 		    consumeStatementLabel() ;  
 			break;
  
-     case 270 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); }  //$NON-NLS-1$
+     case 271 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeExpressionStatement();  
 			break;
  
-    case 279 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 280 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementIfNoElse();  
 			break;
  
-    case 280 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 281 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementIfWithElse();  
 			break;
  
-    case 281 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); }  //$NON-NLS-1$
+    case 282 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementIfWithElse();  
 			break;
  
-    case 282 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 283 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementSwitch() ;  
 			break;
  
-    case 283 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); }  //$NON-NLS-1$
+    case 284 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); }  //$NON-NLS-1$
 		    consumeEmptySwitchBlock() ;  
 			break;
  
-    case 286 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); }  //$NON-NLS-1$
+    case 287 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); }  //$NON-NLS-1$
 		    consumeSwitchBlock() ;  
 			break;
  
-    case 288 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); }  //$NON-NLS-1$
+    case 289 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); }  //$NON-NLS-1$
 		    consumeSwitchBlockStatements() ;  
 			break;
  
-    case 289 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
+    case 290 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
 		    consumeSwitchBlockStatement() ;  
 			break;
  
-    case 291 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
+    case 292 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
 		    consumeSwitchLabels() ;  
 			break;
  
-     case 292 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); }  //$NON-NLS-1$
+     case 293 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); }  //$NON-NLS-1$
 		    consumeCaseLabel();  
 			break;
  
-     case 293 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
+     case 294 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
 		    consumeDefaultLabel();  
 			break;
  
-    case 294 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 295 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementWhile() ;  
 			break;
  
-    case 295 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
+    case 296 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementWhile() ;  
 			break;
  
-    case 296 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
+    case 297 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementDo() ;  
 			break;
  
-    case 297 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
+    case 298 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
 		    consumeStatementFor() ;  
 			break;
  
-    case 298 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
+    case 299 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
 		    consumeStatementFor() ;  
 			break;
  
-    case 299 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
+    case 300 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
 		    consumeForInit() ;  
 			break;
  
-    case 303 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
+    case 304 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
 		    consumeStatementExpressionList() ;  
 			break;
  
-    case 304 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
+    case 305 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeSimpleAssertStatement() ;  
 			break;
  
-    case 305 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
+    case 306 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
 		    consumeAssertStatement() ;  
 			break;
  
-    case 306 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
+    case 307 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementBreak() ;  
 			break;
  
-    case 307 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); }  //$NON-NLS-1$
+    case 308 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementBreakWithLabel() ;  
 			break;
  
-    case 308 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
+    case 309 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementContinue() ;  
 			break;
  
-    case 309 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
+    case 310 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementContinueWithLabel() ;  
 			break;
  
-    case 310 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
+    case 311 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementReturn() ;  
 			break;
  
-    case 311 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
+    case 312 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementThrow();  
 			break;
  
-    case 312 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
+    case 313 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementSynchronized();  
 			break;
  
-    case 313 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
+    case 314 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
 		    consumeOnlySynchronized();  
 			break;
  
-    case 314 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
+    case 315 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
 		    consumeStatementTry(false);  
 			break;
  
-    case 315 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
+    case 316 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
 		    consumeStatementTry(true);  
 			break;
  
-    case 317 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
+    case 318 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
 		    consumeExitTryBlock();  
 			break;
  
-    case 319 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
+    case 320 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
 		    consumeCatches();  
 			break;
  
-    case 320 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN..."); }  //$NON-NLS-1$
+    case 321 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN FormalParameter RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementCatch() ;  
 			break;
  
-    case 322 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
+    case 323 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
 		    consumeLeftParen();  
 			break;
  
-    case 323 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
+    case 324 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
 		    consumeRightParen();  
 			break;
  
-    case 328 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
+    case 329 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayThis();  
 			break;
  
-    case 329 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
+    case 330 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArray();  
 			break;
  
-    case 330 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
+    case 331 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayWithName();  
 			break;
  
-    case 333 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
+    case 334 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayNameThis();  
 			break;
  
-    case 334 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); }  //$NON-NLS-1$
+    case 335 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayNameSuper();  
 			break;
  
-    case 335 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
+    case 336 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayName();  
 			break;
  
-    case 336 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
+    case 337 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayArrayType();  
 			break;
  
-    case 337 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
+    case 338 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayPrimitiveArrayType();  
 			break;
  
-    case 338 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
+    case 339 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayPrimitiveType();  
 			break;
  
-    case 341 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
+    case 342 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
 		    consumeAllocationHeader();  
 			break;
  
-    case 342 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
+    case 343 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionWithTypeArguments();  
 			break;
  
-    case 343 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN"); }  //$NON-NLS-1$
+    case 344 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN"); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpression();  
 			break;
  
-    case 344 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+    case 345 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
 			break;
  
-    case 345 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
-		    consumeClassInstanceCreationExpressionQualified() ;  
-			break;
- 
-    case 346 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+    case 346 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualified() ;  
 			break;
  
     case 347 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+		    consumeClassInstanceCreationExpressionQualified() ;  
+			break;
+ 
+    case 348 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
 			break;
  
-    case 348 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); }  //$NON-NLS-1$
+    case 349 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionName() ;  
 			break;
  
-    case 349 : if (DEBUG) { System.out.println("ClassBodyopt ::="); }  //$NON-NLS-1$
+    case 350 : if (DEBUG) { System.out.println("ClassBodyopt ::="); }  //$NON-NLS-1$
 		    consumeClassBodyopt();  
 			break;
  
-    case 351 : if (DEBUG) { System.out.println("ClassBodySimpleNameopt ::="); }  //$NON-NLS-1$
-		    consumeClassBodyopt();  
-			break;
- 
-    case 353 : if (DEBUG) { System.out.println("EnterAnonymousClassBodySimpleName ::="); }  //$NON-NLS-1$
-		    consumeEnterAnonymousClassBodySimpleName();  
-			break;
- 
-    case 354 : if (DEBUG) { System.out.println("EnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+    case 352 : if (DEBUG) { System.out.println("EnterAnonymousClassBody ::="); }  //$NON-NLS-1$
 		    consumeEnterAnonymousClassBody();  
 			break;
  
-    case 356 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
+    case 354 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
 		    consumeArgumentList();  
 			break;
  
-    case 357 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
+    case 355 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
 		    consumeArrayCreationHeader();  
 			break;
  
-    case 358 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
+    case 356 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
 		    consumeArrayCreationHeader();  
 			break;
  
+    case 357 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+		    consumeArrayCreationExpressionWithoutInitializer();  
+			break;
+ 
+    case 358 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
+		    consumeArrayCreationExpressionWithInitializer();  
+			break;
+ 
     case 359 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithoutInitializer();  
 			break;
  
-    case 360 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
+    case 360 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithInitializer();  
 			break;
  
-    case 361 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
-		    consumeArrayCreationExpressionWithoutInitializer();  
-			break;
- 
-    case 362 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
-		    consumeArrayCreationExpressionWithInitializer();  
-			break;
- 
-    case 364 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
+    case 362 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
 		    consumeDimWithOrWithOutExprs();  
 			break;
  
-     case 366 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
+     case 364 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
 		    consumeDimWithOrWithOutExpr();  
 			break;
  
-     case 367 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
+     case 365 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
 		    consumeDims();  
 			break;
  
-     case 370 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
+     case 368 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
 		    consumeOneDimLoop();  
 			break;
  
-    case 371 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
+    case 369 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(false);  
 			break;
  
-    case 372 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
+    case 370 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(true);  
 			break;
  
-    case 373 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+    case 371 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
 		    consumeMethodInvocationName();  
 			break;
  
-    case 374 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 372 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationNameWithTypeArguments();  
 			break;
  
-    case 375 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 373 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimaryWithTypeArguments();  
 			break;
  
-    case 376 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 374 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimary();  
 			break;
  
-    case 377 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 375 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationSuperWithTypeArguments();  
 			break;
  
-    case 378 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 376 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationSuper();  
 			break;
  
-    case 379 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
+    case 377 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
 		    consumeArrayAccess(true);  
 			break;
  
-    case 380 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
+    case 378 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
 		    consumeArrayAccess(false);  
 			break;
  
-    case 381 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
+    case 379 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
 		    consumeArrayAccess(false);  
 			break;
  
-    case 383 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
+    case 381 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
 		    consumePostfixExpression();  
 			break;
  
-    case 386 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
+    case 384 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS,true);  
 			break;
  
-    case 387 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
+    case 385 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS,true);  
 			break;
  
-    case 388 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
+    case 386 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
 		    consumePushPosition();  
 			break;
  
-    case 391 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+    case 389 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 392 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+    case 390 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 394 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
+    case 392 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS,false);  
 			break;
  
-    case 395 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
+    case 393 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS,false);  
 			break;
  
-    case 397 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
+    case 395 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
 			break;
  
-    case 398 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
+    case 396 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.NOT);  
 			break;
  
-    case 400 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
+    case 398 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithPrimitiveType();  
 			break;
  
-    case 401 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+    case 399 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithGenericsArray();  
 			break;
  
-    case 402 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+    case 400 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithQualifiedGenericsArray();  
 			break;
  
-    case 403 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
+    case 401 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
 		    consumeCastExpressionLL1();  
 			break;
  
-    case 404 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); }  //$NON-NLS-1$
+    case 402 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithNameArray();  
 			break;
  
-    case 405 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
+    case 403 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
 		    consumeOnlyTypeArgumentsForCastExpression();  
 			break;
  
-    case 406 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
+    case 404 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpression();  
 			break;
  
-    case 407 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
+    case 405 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionLL1();  
 			break;
  
-    case 408 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
+    case 406 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionWithQualifiedGenerics();  
 			break;
  
-    case 410 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 408 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
 			break;
  
-    case 411 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 409 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.DIVIDE);  
 			break;
  
-    case 412 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 410 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.REMAINDER);  
 			break;
  
-    case 414 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
+    case 412 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 415 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
+    case 413 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 417 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
+    case 415 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 418 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 416 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 419 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 417 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 421 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
+    case 419 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS);  
 			break;
  
-    case 422 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
+    case 420 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER);  
 			break;
  
-    case 423 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
+    case 421 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 424 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
+    case 422 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 426 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
+    case 424 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
 		    consumeInstanceOfExpression(OperatorIds.INSTANCEOF);  
 			break;
  
-    case 428 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
+    case 426 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 429 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
+    case 427 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 431 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
+    case 429 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND);  
 			break;
  
-    case 433 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
+    case 431 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.XOR);  
 			break;
  
-    case 435 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
+    case 433 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR);  
 			break;
  
-    case 437 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
+    case 435 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND_AND);  
 			break;
  
-    case 439 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+    case 437 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR_OR);  
 			break;
  
-    case 441 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+    case 439 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
 		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 444 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
+    case 442 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
 		    consumeAssignment();  
 			break;
  
-    case 446 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
+    case 444 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
 		    ignoreExpressionAssignment(); 
 			break;
  
-    case 447 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
+    case 445 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(EQUAL);  
 			break;
  
-    case 448 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
+    case 446 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(MULTIPLY);  
 			break;
  
-    case 449 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
+    case 447 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(DIVIDE);  
 			break;
  
-    case 450 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
+    case 448 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(REMAINDER);  
 			break;
  
-    case 451 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
+    case 449 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(PLUS);  
 			break;
  
-    case 452 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
+    case 450 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(MINUS);  
 			break;
  
-    case 453 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 451 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(LEFT_SHIFT);  
 			break;
  
-    case 454 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 452 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(RIGHT_SHIFT);  
 			break;
  
-    case 455 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 453 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 456 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
+    case 454 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(AND);  
 			break;
  
-    case 457 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
+    case 455 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(XOR);  
 			break;
  
-    case 458 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
+    case 456 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(OR);  
 			break;
  
-    case 462 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
+    case 460 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyExpression();  
 			break;
  
-    case 467 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 465 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyClassBodyDeclarationsopt();  
 			break;
  
-    case 468 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+    case 466 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclarationsopt();  
 			break;
  
-     case 469 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
+     case 467 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
 		    consumeDefaultModifiers();  
 			break;
  
-    case 470 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
+    case 468 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
 		    consumeModifiers();  
 			break;
  
-    case 471 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
+    case 469 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyBlockStatementsopt();  
 			break;
  
-     case 473 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
+     case 471 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyDimsopt();  
 			break;
  
-     case 475 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
+     case 473 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyArgumentListopt();  
 			break;
  
-    case 479 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
+    case 477 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
 		    consumeFormalParameterListopt();  
 			break;
  
-     case 483 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+     case 481 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyInterfaceMemberDeclarationsopt();  
 			break;
  
-     case 484 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+     case 482 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeInterfaceMemberDeclarationsopt();  
 			break;
  
-    case 485 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
+    case 483 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
 		    consumeNestedType();  
 			break;
 
-     case 486 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
+     case 484 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyForInitopt();  
 			break;
  
-     case 488 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
+     case 486 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyForUpdateopt();  
 			break;
  
-     case 492 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
+     case 490 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyCatchesopt();  
 			break;
  
-     case 494 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
+     case 492 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
 		    consumeEnumDeclaration();  
 			break;
  
-     case 495 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
+     case 493 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
 		    consumeEnumHeader();  
 			break;
  
-     case 496 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
+     case 494 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
 		    consumeEnumHeaderName();  
 			break;
  
-     case 497 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
+     case 495 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
 		    consumeEnumBodyNoConstants();  
 			break;
  
-     case 498 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
+     case 496 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
 		    consumeEnumBodyNoConstants();  
 			break;
  
-     case 499 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
+     case 497 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
 		    consumeEnumBodyWithConstants();  
 			break;
  
-     case 500 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
+     case 498 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
 		    consumeEnumBodyWithConstants();  
 			break;
  
-    case 502 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
+    case 500 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
 		    consumeEnumConstants();  
 			break;
  
-    case 503 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
+    case 501 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
 		    consumeEnumConstantHeaderName();  
 			break;
  
-    case 504 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
+    case 502 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
 		    consumeEnumConstantHeader();  
 			break;
  
-    case 505 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
+    case 503 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
 		    consumeEnumConstantWithClassBody();  
 			break;
  
-    case 506 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
+    case 504 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
 		    consumeEnumConstantNoClassBody();  
 			break;
  
-    case 507 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+    case 505 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
 		    consumeArguments();  
 			break;
  
-    case 508 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
+    case 506 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyArguments();  
 			break;
  
-    case 510 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
+    case 508 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
 		    consumeEnumDeclarations();  
 			break;
  
-    case 511 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 509 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyEnumDeclarations();  
 			break;
  
-    case 513 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
+    case 511 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatement();  
 			break;
  
-    case 514 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
+    case 512 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatement();  
 			break;
  
-    case 515 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::= for LPAREN Type..."); }  //$NON-NLS-1$
+    case 513 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::= for LPAREN Type..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeader(false);  
 			break;
  
-    case 516 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::= for LPAREN Modifiers Type"); }  //$NON-NLS-1$
+    case 514 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::= for LPAREN Modifiers Type"); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeader(true);  
 			break;
  
-    case 517 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); }  //$NON-NLS-1$
+    case 515 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 518 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); }  //$NON-NLS-1$
+    case 516 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); }  //$NON-NLS-1$
 		    consumeSingleStaticImportDeclarationName();  
 			break;
  
-    case 519 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
+    case 517 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 520 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); }  //$NON-NLS-1$
+    case 518 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); }  //$NON-NLS-1$
 		    consumeStaticImportOnDemandDeclarationName();  
 			break;
  
-    case 521 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
+    case 519 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
 		    consumeTypeArguments();  
 			break;
  
-    case 522 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
+    case 520 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
 		    consumeOnlyTypeArguments();  
 			break;
  
-    case 524 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+    case 522 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentList1();  
 			break;
  
-    case 526 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); }  //$NON-NLS-1$
+    case 524 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); }  //$NON-NLS-1$
 		    consumeTypeArgumentList();  
 			break;
  
-    case 527 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); }  //$NON-NLS-1$
+    case 525 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); }  //$NON-NLS-1$
 		    consumeTypeArgument();  
 			break;
  
-    case 531 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); }  //$NON-NLS-1$
+    case 529 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); }  //$NON-NLS-1$
 		    consumeReferenceType1();  
 			break;
  
-    case 532 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
+    case 530 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentReferenceType1();  
 			break;
  
-    case 534 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+    case 532 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentList2();  
 			break;
  
-    case 537 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 535 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeReferenceType2();  
 			break;
  
-    case 538 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
+    case 536 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentReferenceType2();  
 			break;
  
-    case 540 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+    case 538 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentList3();  
 			break;
  
-    case 543 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 541 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeReferenceType3();  
 			break;
  
-    case 544 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION"); }  //$NON-NLS-1$
+    case 542 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION"); }  //$NON-NLS-1$
 		    consumeWildcard();  
 			break;
  
-    case 545 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds"); }  //$NON-NLS-1$
+    case 543 : if (DEBUG) { System.out.println("Wildcard ::= QUESTION WildcardBounds"); }  //$NON-NLS-1$
 		    consumeWildcardWithBounds();  
 			break;
  
-    case 546 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); }  //$NON-NLS-1$
+    case 544 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); }  //$NON-NLS-1$
 		    consumeWildcardBoundsExtends();  
 			break;
  
-    case 547 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); }  //$NON-NLS-1$
+    case 545 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); }  //$NON-NLS-1$
 		    consumeWildcardBoundsSuper();  
 			break;
  
-    case 548 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER"); }  //$NON-NLS-1$
+    case 546 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION GREATER"); }  //$NON-NLS-1$
 		    consumeWildcard1();  
 			break;
  
-    case 549 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1"); }  //$NON-NLS-1$
+    case 547 : if (DEBUG) { System.out.println("Wildcard1 ::= QUESTION WildcardBounds1"); }  //$NON-NLS-1$
 		    consumeWildcard1WithBounds();  
 			break;
  
-    case 550 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); }  //$NON-NLS-1$
+    case 548 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); }  //$NON-NLS-1$
 		    consumeWildcardBounds1Extends();  
 			break;
  
-    case 551 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); }  //$NON-NLS-1$
+    case 549 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); }  //$NON-NLS-1$
 		    consumeWildcardBounds1Super();  
 			break;
  
-    case 552 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 550 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeWildcard2();  
 			break;
  
-    case 553 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2"); }  //$NON-NLS-1$
+    case 551 : if (DEBUG) { System.out.println("Wildcard2 ::= QUESTION WildcardBounds2"); }  //$NON-NLS-1$
 		    consumeWildcard2WithBounds();  
 			break;
  
-    case 554 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); }  //$NON-NLS-1$
+    case 552 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); }  //$NON-NLS-1$
 		    consumeWildcardBounds2Extends();  
 			break;
  
-    case 555 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); }  //$NON-NLS-1$
+    case 553 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); }  //$NON-NLS-1$
 		    consumeWildcardBounds2Super();  
 			break;
  
-    case 556 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 554 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeWildcard3();  
 			break;
  
-    case 557 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3"); }  //$NON-NLS-1$
+    case 555 : if (DEBUG) { System.out.println("Wildcard3 ::= QUESTION WildcardBounds3"); }  //$NON-NLS-1$
 		    consumeWildcard3WithBounds();  
 			break;
  
-    case 558 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); }  //$NON-NLS-1$
+    case 556 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); }  //$NON-NLS-1$
 		    consumeWildcardBounds3Extends();  
 			break;
  
-    case 559 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); }  //$NON-NLS-1$
+    case 557 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); }  //$NON-NLS-1$
 		    consumeWildcardBounds3Super();  
 			break;
  
-    case 560 : if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier"); }  //$NON-NLS-1$
+    case 558 : if (DEBUG) { System.out.println("TypeParameterHeader ::= Identifier"); }  //$NON-NLS-1$
 		    consumeTypeParameterHeader();  
 			break;
  
-    case 561 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); }  //$NON-NLS-1$
+    case 559 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); }  //$NON-NLS-1$
 		    consumeTypeParameters();  
 			break;
  
-    case 563 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
+    case 561 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeParameterList();  
 			break;
  
-    case 565 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 563 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameterWithExtends();  
 			break;
  
-    case 566 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 564 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameterWithExtendsAndBounds();  
 			break;
  
-    case 568 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); }  //$NON-NLS-1$
+    case 566 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); }  //$NON-NLS-1$
 		    consumeAdditionalBoundList();  
 			break;
  
-    case 569 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); }  //$NON-NLS-1$
+    case 567 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); }  //$NON-NLS-1$
 		    consumeAdditionalBound();  
 			break;
  
-    case 571 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
+    case 569 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeParameterList1();  
 			break;
  
-    case 572 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); }  //$NON-NLS-1$
+    case 570 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); }  //$NON-NLS-1$
 		    consumeTypeParameter1();  
 			break;
  
-    case 573 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 571 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameter1WithExtends();  
 			break;
  
-    case 574 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 572 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameter1WithExtendsAndBounds();  
 			break;
  
-    case 576 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); }  //$NON-NLS-1$
+    case 574 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); }  //$NON-NLS-1$
 		    consumeAdditionalBoundList1();  
 			break;
  
-    case 577 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); }  //$NON-NLS-1$
+    case 575 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); }  //$NON-NLS-1$
 		    consumeAdditionalBound1();  
 			break;
  
-    case 583 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); }  //$NON-NLS-1$
+    case 581 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 584 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); }  //$NON-NLS-1$
+    case 582 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 587 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); }  //$NON-NLS-1$
+    case 585 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
 			break;
  
-    case 588 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); }  //$NON-NLS-1$
+    case 586 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.NOT);  
 			break;
  
-    case 591 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 589 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
 			break;
  
-    case 592 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); }  //$NON-NLS-1$
+    case 590 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.MULTIPLY);  
 			break;
  
-    case 593 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 591 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.DIVIDE);  
 			break;
  
-    case 594 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); }  //$NON-NLS-1$
+    case 592 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.DIVIDE);  
 			break;
  
-    case 595 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 593 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.REMAINDER);  
 			break;
  
-    case 596 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); }  //$NON-NLS-1$
+    case 594 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.REMAINDER);  
 			break;
  
-    case 598 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 596 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 599 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); }  //$NON-NLS-1$
+    case 597 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.PLUS);  
 			break;
  
-    case 600 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 598 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 601 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); }  //$NON-NLS-1$
+    case 599 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.MINUS);  
 			break;
  
-    case 603 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+    case 601 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 604 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); }  //$NON-NLS-1$
+    case 602 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 605 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+    case 603 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 606 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 604 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 607 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+    case 605 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 608 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 606 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 610 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
+    case 608 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS);  
 			break;
  
-    case 611 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); }  //$NON-NLS-1$
+    case 609 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.LESS);  
 			break;
  
-    case 612 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
+    case 610 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER);  
 			break;
  
-    case 613 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); }  //$NON-NLS-1$
+    case 611 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.GREATER);  
 			break;
  
-    case 614 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 612 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 615 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); }  //$NON-NLS-1$
+    case 613 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 616 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 614 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 617 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); }  //$NON-NLS-1$
+    case 615 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 619 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); }  //$NON-NLS-1$
+    case 617 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); }  //$NON-NLS-1$
 		    consumeInstanceOfExpressionWithName(OperatorIds.INSTANCEOF);  
 			break;
  
-    case 620 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 618 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeInstanceOfExpression(OperatorIds.INSTANCEOF);  
 			break;
  
-    case 622 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 620 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 623 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); }  //$NON-NLS-1$
+    case 621 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 624 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 622 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 625 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); }  //$NON-NLS-1$
+    case 623 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 627 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); }  //$NON-NLS-1$
+    case 625 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND);  
 			break;
  
-    case 628 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); }  //$NON-NLS-1$
+    case 626 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.AND);  
 			break;
  
-    case 630 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 628 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.XOR);  
 			break;
  
-    case 631 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); }  //$NON-NLS-1$
+    case 629 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.XOR);  
 			break;
  
-    case 633 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 631 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR);  
 			break;
  
-    case 634 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); }  //$NON-NLS-1$
+    case 632 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.OR);  
 			break;
  
-    case 636 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 634 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND_AND);  
 			break;
  
-    case 637 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); }  //$NON-NLS-1$
+    case 635 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.AND_AND);  
 			break;
  
-    case 639 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 637 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR_OR);  
 			break;
  
-    case 640 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); }  //$NON-NLS-1$
+    case 638 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.OR_OR);  
 			break;
  
-    case 642 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 640 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 643 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); }  //$NON-NLS-1$
+    case 641 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); }  //$NON-NLS-1$
 		    consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 647 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
+    case 645 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeaderName() ;  
 			break;
  
-    case 648 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
+    case 646 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeaderName() ;  
 			break;
  
-    case 649 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); }  //$NON-NLS-1$
+    case 647 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeader() ;  
 			break;
  
-    case 650 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); }  //$NON-NLS-1$
+    case 648 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclaration() ;  
 			break;
  
-    case 652 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 650 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyAnnotationTypeMemberDeclarationsopt() ;  
 			break;
  
-    case 655 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); }  //$NON-NLS-1$
+    case 653 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeMemberDeclarations() ;  
 			break;
  
-    case 656 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); }  //$NON-NLS-1$
+    case 654 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); }  //$NON-NLS-1$
 		    consumeMethodHeaderNameWithTypeParameters(true);  
 			break;
  
-    case 657 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 655 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeMethodHeaderName(true);  
 			break;
  
-    case 658 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); }  //$NON-NLS-1$
+    case 656 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyMethodHeaderDefaultValue() ;  
 			break;
  
-    case 659 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); }  //$NON-NLS-1$
+    case 657 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); }  //$NON-NLS-1$
 		    consumeMethodHeaderDefaultValue();  
 			break;
  
-    case 660 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); }  //$NON-NLS-1$
+    case 658 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodHeader();  
 			break;
  
-    case 661 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); }  //$NON-NLS-1$
+    case 659 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeMemberDeclaration() ;  
 			break;
  
-    case 669 : if (DEBUG) { System.out.println("AnnotationName ::= AT Name"); }  //$NON-NLS-1$
+    case 667 : if (DEBUG) { System.out.println("AnnotationName ::= AT Name"); }  //$NON-NLS-1$
 		    consumeAnnotationName() ;  
 			break;
  
-    case 670 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
+    case 668 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
 		    consumeNormalAnnotation() ;  
 			break;
  
-    case 671 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); }  //$NON-NLS-1$
+    case 669 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyMemberValuePairsopt() ;  
 			break;
  
-    case 674 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); }  //$NON-NLS-1$
+    case 672 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); }  //$NON-NLS-1$
 		    consumeMemberValuePairs() ;  
 			break;
  
-    case 675 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL MemberValue"); }  //$NON-NLS-1$
+    case 673 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); }  //$NON-NLS-1$
 		    consumeMemberValuePair() ;  
 			break;
  
+    case 674 : if (DEBUG) { System.out.println("EnterMemberValue ::="); }  //$NON-NLS-1$
+		    consumeEnterMemberValue() ;  
+			break;
+ 
+    case 675 : if (DEBUG) { System.out.println("ExitMemberValue ::="); }  //$NON-NLS-1$
+		    consumeExitMemberValue() ;  
+			break;
+ 
     case 677 : if (DEBUG) { System.out.println("MemberValue ::= Name"); }  //$NON-NLS-1$
 		    consumeMemberValueAsName() ;  
 			break;
@@ -6132,34 +6164,10 @@
 protected void consumeSingleMemberAnnotation() {
 	// SingleMemberAnnotation ::= '@' Name '(' MemberValue ')'
 	SingleMemberAnnotation singleMemberAnnotation = null;
-	int length = this.identifierLengthStack[this.identifierLengthPtr--];
-	TypeReference typeReference;
-	if (length == 1) {
-		typeReference = new SingleTypeReference(
-				this.identifierStack[this.identifierPtr], 
-				this.identifierPositionStack[this.identifierPtr--]);
-	} else {
-		char[][] tokens = new char[length][];
-		this.identifierPtr -= length;
-		long[] positions = new long[length];
-		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
-		System.arraycopy(
-			this.identifierPositionStack, 
-			this.identifierPtr + 1, 
-			positions, 
-			0, 
-			length);
-		typeReference = new QualifiedTypeReference(tokens, positions);
-	}
+	TypeReference typeReference = this.getAnnotationType();
 	singleMemberAnnotation = new SingleMemberAnnotation(typeReference, this.intStack[this.intPtr--]);
 	singleMemberAnnotation.memberValue = this.expressionStack[this.expressionPtr--];
 	this.expressionLengthPtr--;
-	int sourceStart = singleMemberAnnotation.sourceStart;
-	if (this.modifiersSourceStart < 0) {
-		this.modifiersSourceStart = sourceStart;
-	} else if (this.modifiersSourceStart > sourceStart) {
-		this.modifiersSourceStart = sourceStart;
-	}
 	singleMemberAnnotation.declarationSourceEnd = this.rParenPos;
 	pushOnExpressionStack(singleMemberAnnotation);
 	if(options.sourceLevel < ClassFileConstants.JDK1_5 &&
@@ -7330,6 +7338,7 @@
 	m.thrownExceptions = c.thrownExceptions;
 	m.explicitDeclarations = c.explicitDeclarations;
 	m.returnType = null;
+	m.javadoc = c.javadoc;
 	return m;
 }
 protected TypeReference copyDims(TypeReference typeRef, int dim) {
@@ -7554,14 +7563,14 @@
 	if (this.currentElement != null){
 		this.currentElement.topElement().updateParseTree();
 		if (VERBOSE_RECOVERY){
-			System.out.print(Util.bind("parser.syntaxRecovery")); //$NON-NLS-1$
+			System.out.print(Messages.parser_syntaxRecovery); 
 			System.out.println("--------------------------");		 //$NON-NLS-1$
 			System.out.println(this.compilationUnit);		
 			System.out.println("----------------------------------"); //$NON-NLS-1$
 		}		
 	} else {
 		if (this.diet & VERBOSE_RECOVERY){
-			System.out.print(Util.bind("parser.regularParse"));	 //$NON-NLS-1$
+			System.out.print(Messages.parser_regularParse); 
 			System.out.println("--------------------------");	 //$NON-NLS-1$
 			System.out.println(this.compilationUnit);		
 			System.out.println("----------------------------------"); //$NON-NLS-1$
@@ -7625,13 +7634,52 @@
 
 	if (index < 0) return position; // no obsolete comment
 
-	if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos
-		System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
-		System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);		
+	switch (validCount) {
+		case 0:
+			// do nothing
+			break;
+		// move valid comment infos, overriding obsolete comment infos
+		case 2:
+			this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+			this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+			this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+			this.scanner.commentStarts[1] = this.scanner.commentStarts[index+2];
+			this.scanner.commentStops[1] = this.scanner.commentStops[index+2];
+			this.scanner.commentTagStarts[1] = this.scanner.commentTagStarts[index+2];
+			break;
+		case 1:
+			this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+			this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+			this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+			break;
+		default:
+			System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
+			System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);		
+			System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount);
 	}
 	this.scanner.commentPtr = validCount - 1;
 	return position;
 }
+protected TypeReference getAnnotationType() {
+	int length = this.identifierLengthStack[this.identifierLengthPtr--];
+	if (length == 1) {
+		return new SingleTypeReference(
+				this.identifierStack[this.identifierPtr], 
+				this.identifierPositionStack[this.identifierPtr--]);
+	} else {
+		char[][] tokens = new char[length][];
+		this.identifierPtr -= length;
+		long[] positions = new long[length];
+		System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+		System.arraycopy(
+			this.identifierPositionStack, 
+			this.identifierPtr + 1, 
+			positions, 
+			0, 
+			length);
+		return new QualifiedTypeReference(tokens, positions);
+	}
+}
 public int getFirstToken() {
 	// the first token is a virtual token that
 	// allows the parser to parse several goals
@@ -8024,97 +8072,6 @@
 	// report a syntax error and abort parsing
 	problemReporter().arrayConstantsOnlyInArrayInitializers(arrayInitializer.sourceStart, arrayInitializer.sourceEnd); 	
 }
-protected void ignoreInterfaceDeclaration() {
-	// BlockStatement ::= InvalidInterfaceDeclaration
-	//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
-
-	// length declarations
-	int length;
-	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
-		//there are length declarations
-		//dispatch according to the type of the declarations
-		dispatchDeclarationInto(length);
-	}
-	
-	flushCommentsDefinedPriorTo(this.endStatementPosition);
-
-	// report the problem and continue parsing
-	TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
-	typeDecl.bodyEnd = this.endStatementPosition;
-	problemReporter().cannotDeclareLocalInterface(typeDecl.name, typeDecl.sourceStart, typeDecl.sourceEnd);
-
-	// mark initializers with local type mark if needed
-	markInitializersWithLocalType(typeDecl);
-
-	// remove the ast node created in interface header
-	this.astPtr--;
-	pushOnAstLengthStack(-1);
-	concatNodeLists();
-}
-protected void ignoreInvalidConstructorDeclaration(boolean hasBody) {
-	// InvalidConstructorDeclaration ::= ConstructorHeader ConstructorBody ==> true
-	// InvalidConstructorDeclaration ::= ConstructorHeader ';' ==> false
-
-	/*
-	this.astStack : modifiers arguments throws statements
-	this.identifierStack : name
-	 ==>
-	this.astStack : MethodDeclaration
-	this.identifierStack :
-	*/
-	if (hasBody) {
-		// pop the position of the {  (body of the method) pushed in block decl
-		this.intPtr--;
-	}
-
-	//statements
-	if (hasBody) {
-		this.realBlockPtr--;
-	}
-
-	int length;
-	if (hasBody && ((length = this.astLengthStack[this.astLengthPtr--]) != 0)) {
-		this.astPtr -= length;
-	}
-	ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) this.astStack[this.astPtr];
-	constructorDeclaration.bodyEnd = this.endStatementPosition;
-	constructorDeclaration.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
-	if (!hasBody) {
-		constructorDeclaration.modifiers |= AccSemicolonBody;
-	}
-}
-protected void ignoreMethodBody() {
-	// InterfaceMemberDeclaration ::= InvalidMethodDeclaration
-
-	/*
-	this.astStack : modifiers arguments throws statements
-	this.identifierStack : type name
-	this.intStack : dim dim dim
-	 ==>
-	this.astStack : MethodDeclaration
-	this.identifierStack :
-	this.intStack : 
-	*/
-
-	// pop the position of the {  (body of the method) pushed in block decl
-	this.intPtr--;
-	// retrieve end position of method declarator
-
-	//statements
-	this.realBlockPtr--;
-	int length;
-	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
-		this.astPtr -= length;
-	}
-
-	//watch for } that could be given as a unicode ! ( u007D is '}' )
-	MethodDeclaration md = (MethodDeclaration) this.astStack[this.astPtr];
-	md.bodyEnd = this.endPosition;
-	md.declarationSourceEnd = flushCommentsDefinedPriorTo(this.endStatementPosition);
-
-	// report the problem and continue the parsing - narrowing the problem onto the method
-	problemReporter().abstractMethodNeedingNoBody(md);
-}
 public void initialize() {
 	//positionning the parser for a new compilation unit
 	//avoiding stack reallocation and all that....
@@ -8188,6 +8145,7 @@
 		false /*whitespace*/, 
 		this.options.getSeverity(CompilerOptions.NonExternalizedString) != ProblemSeverities.Ignore /*nls*/, 
 		this.options.sourceLevel /*sourceLevel*/, 
+		this.options.complianceLevel /*complianceLevel*/, 
 		this.options.taskTags/*taskTags*/,
 		this.options.taskPriorites/*taskPriorities*/,
 		this.options.isTaskCaseSensitive/*taskCaseSensitive*/);
@@ -9354,4 +9312,4 @@
 	exp.sourceEnd = this.intStack[this.intPtr--];
 	exp.sourceStart = this.intStack[this.intPtr--];
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
index 6360b0f..b277b64 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,22 +14,22 @@
  about the parser such as the number of rules in the grammar, the starting state, etc...*/
 public interface ParserBasicInformation {
 
-	int ERROR_SYMBOL = 108,
+	int ERROR_SYMBOL = 110,
 		MAX_NAME_LENGTH = 41,
 		NUM_STATES = 953,
 
-		NT_OFFSET = 108,
-		SCOPE_UBOUND = 132,
-		SCOPE_SIZE = 133,
-		LA_STATE_OFFSET = 12548,
+		NT_OFFSET = 110,
+		SCOPE_UBOUND = 131,
+		SCOPE_SIZE = 132,
+		LA_STATE_OFFSET = 12568,
 		MAX_LA = 1,
 		NUM_RULES = 691,
-		NUM_TERMINALS = 108,
-		NUM_NON_TERMINALS = 307,
-		NUM_SYMBOLS = 415,
-		START_STATE = 1129,
-		EOFT_SYMBOL = 67,
-		EOLT_SYMBOL = 67,
-		ACCEPT_ACTION = 12547,
-		ERROR_ACTION = 12548;
-}
\ No newline at end of file
+		NUM_TERMINALS = 110,
+		NUM_NON_TERMINALS = 306,
+		NUM_SYMBOLS = 416,
+		START_STATE = 1045,
+		EOFT_SYMBOL = 66,
+		EOLT_SYMBOL = 66,
+		ACCEPT_ACTION = 12567,
+		ERROR_ACTION = 12568;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
index 9917bd9..3e4c38a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
index bea72d2..28e4691 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
index a3849d4..91f1751 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -113,16 +113,28 @@
 	if (this.anonymousTypes != null) {
 		if(fieldDeclaration.initialization == null) {
 			for (int i = 0; i < this.anonymousTypeCount; i++){
-				if (anonymousTypes[i].preserveContent){
-					fieldDeclaration.initialization = this.anonymousTypes[i].updatedTypeDeclaration().allocation;
+				RecoveredType recoveredType = anonymousTypes[i];
+				TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
+				if(typeDeclaration.declarationSourceEnd == 0) {
+					typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
+					typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
+				}
+				if (recoveredType.preserveContent){
+					fieldDeclaration.initialization = recoveredType.updatedTypeDeclaration().allocation;
 				}
 			}
 			if (this.anonymousTypeCount > 0) fieldDeclaration.bits |= ASTNode.HasLocalTypeMASK;
 		} else if(fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
 			// fieldDeclaration is an enum constant
 			for (int i = 0; i < this.anonymousTypeCount; i++){
-				if (anonymousTypes[i].preserveContent){
-					this.anonymousTypes[i].updatedTypeDeclaration();
+				RecoveredType recoveredType = anonymousTypes[i];
+				TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
+				if(typeDeclaration.declarationSourceEnd == 0) {
+					typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
+					typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
+				}
+				if (recoveredType.preserveContent){
+					recoveredType.updatedTypeDeclaration();
 				}
 			}
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java
index a86c81a..57505af 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java
index ed9d6c3..364afc5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
index 27b2fb2..3248afa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
index 64e38f5..193ac00 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,6 +19,7 @@
 import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
 import org.eclipse.jdt.internal.compiler.ast.Statement;
 import org.eclipse.jdt.internal.compiler.ast.SuperReference;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -358,6 +359,19 @@
 				int argLength = parser.astLengthStack[parser.astLengthPtr];
 				int argStart = parser.astPtr - argLength + 1;
 				boolean needUpdateRParenPos = parser.rParenPos < parser.lParenPos; // 12387 : rParenPos will be used
+				
+				// remove unfinished annotation nodes
+				MemberValuePair[] memberValuePairs = null;
+				if (argLength > 0 && parser.astStack[parser.astPtr] instanceof MemberValuePair) {
+					System.arraycopy(parser.astStack, argStart, memberValuePairs = new MemberValuePair[argLength], 0, argLength);
+					parser.astLengthPtr--;
+					parser.astPtr -= argLength;
+					
+					argLength = parser.astLengthStack[parser.astLengthPtr];
+					argStart = parser.astPtr - argLength + 1;
+					needUpdateRParenPos = true;
+				}
+				
 				// to compute bodyStart, and thus used to set next checkpoint.
 				int count;
 				for (count = 0; count < argLength; count++){
@@ -401,6 +415,12 @@
 						}
 					}
 				}
+				
+				if(memberValuePairs != null) {
+					System.arraycopy(memberValuePairs, 0, parser.astStack, parser.astPtr + 1, memberValuePairs.length);
+					parser.astPtr += memberValuePairs.length;
+					parser.astLengthStack[++parser.astLengthPtr] = memberValuePairs.length;
+				}
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
index adbb79e..c3c3f0e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
index c93242e..15c475b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java
index 73a9e49..a3f3de9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index 6ec4cf4..feb4892 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -26,7 +26,9 @@
  * which constant values reflect the latest parser generation state.
  */
 public class Scanner implements TerminalTokens {
-
+	
+	//public int newIdentCount = 0;
+	
 	/* APIs ares
 	 - getNextToken() which return the current type of the token
 	   (this value is not memorized by the scanner)
@@ -36,6 +38,8 @@
 	 - currentPosition-1 gives the sourceEnd position into the stream 
 	*/
 	protected long sourceLevel;
+	protected long complianceLevel;
+
 	// 1.4 feature 
 	public boolean useAssertAsAnIndentifier = false;
 	//flag indicating if processed source contains occurrences of keyword assert 
@@ -66,8 +70,10 @@
 	public boolean scanningFloatLiteral = false;
 
 	//support for /** comments
-	public int[] commentStops = new int[10];
-	public int[] commentStarts = new int[10];
+	public static int COMMENT_ARRAYS_SIZE = 30;
+	public int[] commentStops = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentStarts = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentTagStarts = new int[COMMENT_ARRAYS_SIZE];
 	public int commentPtr = -1; // no comment test with commentPtr value -1
 	protected int lastCommentLinePosition = -1;
 	
@@ -99,12 +105,15 @@
 	public static final String INVALID_INPUT = "Invalid_Input"; //$NON-NLS-1$
 	public static final String INVALID_UNICODE_ESCAPE = "Invalid_Unicode_Escape"; //$NON-NLS-1$
 	public static final String INVALID_FLOAT = "Invalid_Float_Literal"; //$NON-NLS-1$
+	public static final String INVALID_LOW_SURROGATE = "Invalid_Low_Surrogate"; //$NON-NLS-1$
+	public static final String INVALID_HIGH_SURROGATE = "Invalid_High_Surrogate"; //$NON-NLS-1$
 
 	public static final String NULL_SOURCE_STRING = "Null_Source_String"; //$NON-NLS-1$
 	public static final String UNTERMINATED_STRING = "Unterminated_String"; //$NON-NLS-1$
 	public static final String UNTERMINATED_COMMENT = "Unterminated_Comment"; //$NON-NLS-1$
 	public static final String INVALID_CHAR_IN_STRING = "Invalid_Char_In_String"; //$NON-NLS-1$
-	public static final String INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$	
+	public static final String INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$
+	private static final int[] EMPTY_LINE_ENDS = new int[0];
 
 	//----------------optimized identifier managment------------------
 	static final char[] charArray_a = new char[] {'a'}, 
@@ -136,8 +145,60 @@
 
 	static final char[] initCharArray = 
 		new char[] {'\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000'}; 
-	static final int TableSize = 30, InternalTableSize = 6; //30*6 = 180 entries
-	public static final int OptimizedLength = 6;
+	static final int TableSize = 30, InternalTableSize = 6; //30*6 =210 entries
+	
+	public final static int MAX_OBVIOUS = 128;
+	static final int[] ObviousIdentCharNatures = new int[MAX_OBVIOUS];
+	public final static int C_LETTER = 4;
+	public final static int C_DIGIT = 3;
+	public final static int C_SEPARATOR = 2;
+	public final static int C_SPACE = 1;
+	static {
+		for (int i = '0'; i <= '9'; i++) 
+			ObviousIdentCharNatures[i] = C_DIGIT;
+		
+		for (int i = 'a'; i <= 'z'; i++) 
+			ObviousIdentCharNatures[i] = C_LETTER;
+		for (int i = 'A'; i <= 'Z'; i++) 
+			ObviousIdentCharNatures[i] = C_LETTER;
+		ObviousIdentCharNatures['_'] = C_LETTER;
+		ObviousIdentCharNatures['$'] = C_LETTER;
+		
+		ObviousIdentCharNatures[10] = C_SPACE; // \ u000a: LINE FEED
+		ObviousIdentCharNatures[12] = C_SPACE; // \ u000c: FORM FEED
+		ObviousIdentCharNatures[13] = C_SPACE; //  \ u000d: CARRIAGE RETURN
+		ObviousIdentCharNatures[32] = C_SPACE; //  \ u0020: SPACE
+		ObviousIdentCharNatures[ 9] = C_SPACE; // \ u0009: HORIZONTAL TABULATION
+		
+		ObviousIdentCharNatures['.'] = C_SEPARATOR;
+		ObviousIdentCharNatures[':'] = C_SEPARATOR;
+		ObviousIdentCharNatures[';'] = C_SEPARATOR;
+		ObviousIdentCharNatures[','] = C_SEPARATOR;
+		ObviousIdentCharNatures['['] = C_SEPARATOR;
+		ObviousIdentCharNatures[']'] = C_SEPARATOR;
+		ObviousIdentCharNatures['('] = C_SEPARATOR;
+		ObviousIdentCharNatures[')'] = C_SEPARATOR;
+		ObviousIdentCharNatures['{'] = C_SEPARATOR;
+		ObviousIdentCharNatures['}'] = C_SEPARATOR;
+		ObviousIdentCharNatures['+'] = C_SEPARATOR;
+		ObviousIdentCharNatures['-'] = C_SEPARATOR;
+		ObviousIdentCharNatures['*'] = C_SEPARATOR;
+		ObviousIdentCharNatures['/'] = C_SEPARATOR;
+		ObviousIdentCharNatures['='] = C_SEPARATOR;
+		ObviousIdentCharNatures['&'] = C_SEPARATOR;
+		ObviousIdentCharNatures['|'] = C_SEPARATOR;
+		ObviousIdentCharNatures['?'] = C_SEPARATOR;
+		ObviousIdentCharNatures['<'] = C_SEPARATOR;
+		ObviousIdentCharNatures['>'] = C_SEPARATOR;
+		ObviousIdentCharNatures['!'] = C_SEPARATOR;
+		ObviousIdentCharNatures['%'] = C_SEPARATOR;
+		ObviousIdentCharNatures['^'] = C_SEPARATOR;
+		ObviousIdentCharNatures['~'] = C_SEPARATOR;
+		ObviousIdentCharNatures['"'] = C_SEPARATOR;
+		ObviousIdentCharNatures['\''] = C_SEPARATOR;
+	}
+	
+	public static final int OptimizedLength = 7;
 	public /*static*/ final char[][][][] charArray_length = 
 		new char[OptimizedLength][TableSize][InternalTableSize][]; 
 	// support for detecting non-externalized string literals
@@ -162,7 +223,7 @@
 			}
 		}
 	}
-	static int newEntry2 = 0, 
+	/*static*/ int newEntry2 = 0, 
 		newEntry3 = 0, 
 		newEntry4 = 0, 
 		newEntry5 = 0, 
@@ -172,6 +233,12 @@
 	public static final int SquareBracket = 1;
 	public static final int CurlyBracket = 2;	
 	public static final int BracketKinds = 3;
+	
+	// extended unicode support
+	public static final int LOW_SURROGATE_MIN_VALUE = 0xDC00;
+	public static final int HIGH_SURROGATE_MIN_VALUE = 0xD800;
+	public static final int HIGH_SURROGATE_MAX_VALUE = 0xDBFF;
+	public static final int LOW_SURROGATE_MAX_VALUE = 0xDFFF;
 
 public Scanner() {
 	this(false /*comment*/, false /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
@@ -182,6 +249,27 @@
 	boolean tokenizeWhiteSpace, 
 	boolean checkNonExternalizedStringLiterals, 
 	long sourceLevel,
+	long complianceLevel,
+	char[][] taskTags,
+	char[][] taskPriorities,
+	boolean isTaskCaseSensitive) {
+
+	this.eofPosition = Integer.MAX_VALUE;
+	this.tokenizeComments = tokenizeComments;
+	this.tokenizeWhiteSpace = tokenizeWhiteSpace;
+	this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
+	this.sourceLevel = sourceLevel;
+	this.complianceLevel = complianceLevel;
+	this.taskTags = taskTags;
+	this.taskPriorities = taskPriorities;
+	this.isTaskCaseSensitive = isTaskCaseSensitive;
+}
+
+public Scanner(
+	boolean tokenizeComments, 
+	boolean tokenizeWhiteSpace, 
+	boolean checkNonExternalizedStringLiterals, 
+	long sourceLevel,
 	char[][] taskTags,
 	char[][] taskPriorities,
 	boolean isTaskCaseSensitive) {
@@ -191,6 +279,7 @@
 	this.tokenizeWhiteSpace = tokenizeWhiteSpace;
 	this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
 	this.sourceLevel = sourceLevel;
+	this.complianceLevel = sourceLevel;
 	this.taskTags = taskTags;
 	this.taskPriorities = taskPriorities;
 	this.isTaskCaseSensitive = isTaskCaseSensitive;
@@ -211,7 +300,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) {
+public void checkTaskTag(int commentStart, int commentEnd) throws InvalidInputException {
 	char[] src = this.source;
 	
 	// only look for newer task: tags
@@ -325,6 +414,7 @@
 		this.foundTaskMessages[i] = message;
 	}
 }
+
 public char[] getCurrentIdentifierSource() {
 	//return the token REAL source (aka unicodes are precomputed)
 
@@ -357,6 +447,7 @@
 		//no optimization
 		System.arraycopy(this.source, this.startPosition, result = new char[length], 0, length);
 	}
+	//newIdentCount++;
 	return result;
 }
 public int getCurrentTokenEndPosition(){
@@ -385,6 +476,21 @@
 	}
 	return result;
 }
+public final String getCurrentTokenString() {
+	// Return current token as a string
+
+	if (this.withoutUnicodePtr != 0) {
+		// 0 is used as a fast test flag so the real first char is in position 1
+		return new String(
+			this.withoutUnicodeBuffer, 
+			1, 
+			this.withoutUnicodePtr);
+	}
+	return new String(
+		this.source, 
+		this.startPosition, 
+		this.currentPosition - this.startPosition); 
+}
 public final char[] getCurrentTokenSourceString() {
 	//return the token REAL source (aka unicodes are precomputed).
 	//REMOVE the two " that are at the beginning and the end.
@@ -406,7 +512,18 @@
 	}
 	return result;
 }
+public final String getCurrentStringLiteral() {
+	//return the token REAL source (aka unicodes are precomputed).
+	//REMOVE the two " that are at the beginning and the end.
 
+	if (this.withoutUnicodePtr != 0)
+		//0 is used as a fast test flag so the real first char is in position 1
+		//2 is 1 (real start) + 1 (to jump over the ")
+		return new String(this.withoutUnicodeBuffer, 2, this.withoutUnicodePtr - 2);
+	else {
+		return new String(this.source, this.startPosition + 1, this.currentPosition - this.startPosition - 2);
+	}
+}
 public final char[] getRawTokenSource() {
 	int length = this.currentPosition - this.startPosition;
 	char[] tokenSource = new char[length];
@@ -434,7 +551,7 @@
  */
 public final int getLineEnd(int lineNumber) {
 
-	if (this.lineEnds == null) 
+	if (this.lineEnds == null || this.linePtr == -1) 
 		return -1;
 	if (lineNumber > this.lineEnds.length+1) 
 		return -1;
@@ -446,8 +563,10 @@
 }
 
 public final int[] getLineEnds() {
-	//return a bounded copy of this.lineEnds 
-
+	//return a bounded copy of this.lineEnds
+	if (this.linePtr == -1) {
+		return EMPTY_LINE_ENDS;
+	}
 	int[] copy;
 	System.arraycopy(this.lineEnds, 0, copy = new int[this.linePtr + 1], 0, this.linePtr + 1);
 	return copy;
@@ -468,7 +587,7 @@
  */
 public final int getLineStart(int lineNumber) {
 
-	if (this.lineEnds == null) 
+	if (this.lineEnds == null || this.linePtr == -1) 
 		return -1;
 	if (lineNumber > this.lineEnds.length + 1) 
 		return -1;
@@ -483,46 +602,18 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				return -1;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-
-			this.unicodeAsBackSlash = this.currentCharacter == '\\';
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
-			return this.currentCharacter;
-
-		} //-------------end unicode traitement--------------
-		else {
+				getNextUnicodeChar();
+		} else {
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0) {
-			    unicodeStoreAt(++this.withoutUnicodePtr);
+			    unicodeStore();
 			}
-			return this.currentCharacter;
 		}
+		return this.currentCharacter;
 	} catch (IndexOutOfBoundsException e) {
 		return -1;
+	} catch(InvalidInputException e) {
+		return -1;
 	}
 }
 public final boolean getNextChar(char testedChar) {
@@ -545,40 +636,13 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			getNextUnicodeChar();
 			if (this.currentCharacter != testedChar) {
 				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
 				return false;
 			}
-			this.unicodeAsBackSlash = this.currentCharacter == '\\';
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-
 		} //-------------end unicode traitement--------------
 		else {
 			if (this.currentCharacter != testedChar) {
@@ -587,13 +651,17 @@
 			}
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.unicodeAsBackSlash = false;
 		this.currentPosition = temp;
 		return false;
+	} catch(InvalidInputException e) {
+		this.unicodeAsBackSlash = false;
+		this.currentPosition = temp;
+		return false;
 	}
 }
 public final int getNextChar(char testedChar1, char testedChar2) {
@@ -615,62 +683,37 @@
 		int result;
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
+			getNextUnicodeChar();
+			if (this.currentCharacter == testedChar1) {
+				result = 0;
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
 				this.currentPosition = temp;
-				return 2;
+				this.withoutUnicodePtr--;
+				result = -1;
 			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			if (this.currentCharacter == testedChar1)
-				result = 0;
-			else
-				if (this.currentCharacter == testedChar2)
-					result = 1;
-				else {
-					this.currentPosition = temp;
-					return -1;
-				}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return result;
-		} //-------------end unicode traitement--------------
-		else {
-			if (this.currentCharacter == testedChar1)
+		} else {
+			if (this.currentCharacter == testedChar1) {
 				result = 0;
-			else
-				if (this.currentCharacter == testedChar2)
-					result = 1;
-				else {
-					this.currentPosition = temp;
-					return -1;
-				}
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
+				this.currentPosition = temp;
+				return -1;
+			}
 
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return result;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.currentPosition = temp;
 		return -1;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return -1;
 	}
 }
 public final boolean getNextCharAsDigit() throws InvalidInputException {
@@ -690,51 +733,28 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			getNextUnicodeChar();
 			if (!isDigit(this.currentCharacter)) {
 				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
 				return false;
 			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-		} //-------------end unicode traitement--------------
-		else {
+		} else {
 			if (!isDigit(this.currentCharacter)) {
 				this.currentPosition = temp;
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.currentPosition = temp;
 		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
 	}
 }
 public final boolean getNextCharAsDigit(int radix) {
@@ -754,51 +774,28 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			getNextUnicodeChar();
 			if (Character.digit(this.currentCharacter, radix) == -1) {
 				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
 				return false;
 			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-		} //-------------end unicode traitement--------------
-		else {
+		} else {
 			if (Character.digit(this.currentCharacter, radix) == -1) {
 				this.currentPosition = temp;
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.currentPosition = temp;
 		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
 	}
 }
 public boolean getNextCharAsJavaIdentifierPart() {
@@ -811,58 +808,67 @@
 	//On false, no side effect has occured.
 
 	//ALL getNextChar.... ARE OPTIMIZED COPIES 
-	if (this.currentPosition >= this.source.length) // handle the obvious case upfront
+	int pos;
+	if ((pos = this.currentPosition) >= this.source.length) // handle the obvious case upfront
 		return false;
 
-	int temp = this.currentPosition;
+	int temp2 = this.withoutUnicodePtr;
 	try {
+		boolean unicode = false;
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
+			getNextUnicodeChar();
+			unicode = true;
+		}
+		char c = this.currentCharacter;
+		boolean isJavaIdentifierPart = false;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
 				return false;
 			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			if (!Character.isJavaIdentifierPart(this.currentCharacter)) {
-				this.currentPosition = temp;
+			// Unicode 4 detection
+			char low = (char) getNextChar();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
 				return false;
 			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(c, low);
+		}
+		else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			this.currentPosition = pos;
+			this.withoutUnicodePtr = temp2;
+			return false;
+		} else {
+			isJavaIdentifierPart = Character.isJavaIdentifierPart(c);
+		}
+		if (unicode) {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
 			}
-			//fill the buffer with the char
-		    unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-		} //-------------end unicode traitement--------------
-		else {
-			if (!Character.isJavaIdentifierPart(this.currentCharacter)) {
-				this.currentPosition = temp;
+		} else {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
 				return false;
 			}
 
 			if (this.withoutUnicodePtr != 0)
-			    unicodeStoreAt(++this.withoutUnicodePtr);
+			    unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
-		this.currentPosition = temp;
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
 		return false;
 	}
 }
@@ -882,10 +888,13 @@
 			// ---------Consume white space and handles startPosition---------
 			whiteStart = this.currentPosition;
 			boolean isWhiteSpace, hasWhiteSpaces = false;
-			int offset = 0;
+			int offset;
+			int unicodePtr;
+			boolean checkIfUnicode = false;
 			do {
+				unicodePtr = this.withoutUnicodePtr;
+				offset = this.currentPosition;
 				this.startPosition = this.currentPosition;
-				boolean checkIfUnicode = false;
 				try {
 					checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 						&& (this.source[this.currentPosition] == 'u');
@@ -901,9 +910,9 @@
 				}
 				if (checkIfUnicode) {
 					isWhiteSpace = jumpOverUnicodeWhiteSpace();
-					offset = 6;
+					offset = this.currentPosition - offset;
 				} else {
-					offset = 1;
+					offset = this.currentPosition - offset;
 					if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
 						checkNonExternalizedString();
 						if (this.recordLineSeparator) {
@@ -912,18 +921,40 @@
 							this.currentLine = null;
 						}
 					}
-					isWhiteSpace = 
-						(this.currentCharacter == ' ') || CharOperation.isWhitespace(this.currentCharacter); 
+					// inline version of:
+					//isWhiteSpace = 
+					//	(this.currentCharacter == ' ') || CharOperation.isWhitespace(this.currentCharacter); 
+					switch (this.currentCharacter) {
+						case 10 : /* \ u000a: LINE FEED               */
+						case 12 : /* \ u000c: FORM FEED               */
+						case 13 : /* \ u000d: CARRIAGE RETURN         */
+						case 32 : /* \ u0020: SPACE                   */
+						case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+							isWhiteSpace = true;
+							break;
+						default :
+							isWhiteSpace = false;
+					}
 				}
 				if (isWhiteSpace) {
 					hasWhiteSpaces = true;
 				}
 			} while (isWhiteSpace);
-			if (this.tokenizeWhiteSpace && hasWhiteSpaces) {
-				// reposition scanner in case we are interested by spaces as tokens
-				this.currentPosition-=offset;
-				this.startPosition = whiteStart;
-				return TokenNameWHITESPACE;
+			if (hasWhiteSpaces) {
+				if (this.tokenizeWhiteSpace) {
+					// reposition scanner in case we are interested by spaces as tokens
+					this.currentPosition-=offset;
+					this.startPosition = whiteStart;
+					if (checkIfUnicode) {
+						this.withoutUnicodePtr = unicodePtr;
+					}
+					return TokenNameWHITESPACE;
+				} else if (checkIfUnicode) {
+					this.withoutUnicodePtr = 0;
+					unicodeStore();
+				} else {
+					this.withoutUnicodePtr = 0;
+				}
 			}
 			//little trick to get out in the middle of a source compuation
 			if (this.currentPosition > this.eofPosition)
@@ -1116,11 +1147,24 @@
 						}
 						throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
 					}
-					if (getNextChar('\\'))
+					if (getNextChar('\\')) {
+						if (this.unicodeAsBackSlash) {
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} else {
+							this.currentCharacter = this.source[this.currentPosition++];
+						}
 						scanEscapeCharacter();
-					else { // consume next character
+					} else { // consume next character
 						this.unicodeAsBackSlash = false;
-						boolean checkIfUnicode = false;
+						checkIfUnicode = false;
 						try {
 							checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 							&& (this.source[this.currentPosition] == 'u');
@@ -1132,7 +1176,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 					}
@@ -1161,7 +1205,7 @@
 							isUnicode = true;
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 
@@ -1196,20 +1240,25 @@
 								throw new InvalidInputException(INVALID_CHAR_IN_STRING);
 							}
 							if (this.currentCharacter == '\\') {
-								int escapeSize = this.currentPosition;
-								boolean backSlashAsUnicodeInString = this.unicodeAsBackSlash;
-								//scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
-								scanEscapeCharacter();
-								escapeSize = this.currentPosition - escapeSize;
-								if (this.withoutUnicodePtr == 0) {
-									//buffer all the entries that have been left aside....
-								    unicodeInitializeBuffer(this.currentPosition - escapeSize - 1 - this.startPosition);
-								    unicodeStoreAt(++this.withoutUnicodePtr);
-								} else { //overwrite the / in the buffer
-								    unicodeStoreAt(this.withoutUnicodePtr);
-									if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
+								if (this.unicodeAsBackSlash) {
+									this.withoutUnicodePtr--;
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
 										this.withoutUnicodePtr--;
 									}
+								} else {
+									if (this.withoutUnicodePtr == 0) {
+										unicodeInitializeBuffer(this.currentPosition - this.startPosition);
+									}
+									this.withoutUnicodePtr --;
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								// we need to compute the escape character in a separate buffer
+								scanEscapeCharacter();
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
 								}
 							}
 							// consume next character
@@ -1219,7 +1268,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									unicodeStoreAt(++this.withoutUnicodePtr);
+									unicodeStore();
 								}
 							}
 
@@ -1262,25 +1311,8 @@
 							this.lastCommentLinePosition = this.currentPosition;
 							try { //get the next char 
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
-									//-------------unicode traitement ------------
-									int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-									this.currentPosition++;
-									while (this.source[this.currentPosition] == 'u') {
-										this.currentPosition++;
-									}
-									if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c1 < 0
-										|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c2 < 0
-										|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c3 < 0
-										|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c4 < 0) {
-										throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-									} else {
-										this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-									}
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
 								}
 
 								//handle the \\u case manually into comment
@@ -1294,26 +1326,9 @@
 									//get the next char
 									isUnicode = false;									
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-										&& (this.source[this.currentPosition] == 'u')) {
-										isUnicode = true;											
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										this.currentPosition++;
-										while (this.source[this.currentPosition] == 'u') {
-											this.currentPosition++;
-										}
-										if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c4 < 0) {
-											throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-										} else {
-											this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
+											&& (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
 									}
 									//handle the \\u case manually into comment
 									if (this.currentCharacter == '\\') {
@@ -1331,32 +1346,8 @@
 										this.currentCharacter = '\n';
 								   	} else if ((this.source[this.currentPosition] == '\\')
 										&& (this.source[this.currentPosition + 1] == 'u')) {
+										getNextUnicodeChar();
 										isUnicode = true;
-										char unicodeChar;
-										int index = this.currentPosition + 1;
-										index++;
-										while (this.source[index] == 'u') {
-											index++;
-										}
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										if ((c1 = Character.getNumericValue(this.source[index++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[index++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[index++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[index++])) > 15
-											|| c4 < 0) {
-											this.currentPosition = index;
-											throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-										} else {
-											unicodeChar = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
-										if (unicodeChar == '\n') {
-											this.currentPosition = index;
-											this.currentCharacter = '\n';
-										}
 									}
 							   	}
 								recordComment(TokenNameCOMMENT_LINE);
@@ -1392,6 +1383,7 @@
 							try { //get the next char
 								boolean isJavadoc = false, star = false;
 								boolean isUnicode = false;
+								int previous;
 								// consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
@@ -1401,10 +1393,10 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-										unicodeStoreAt(++this.withoutUnicodePtr);
+										unicodeStore();
 									}
 								}
-	
+
 								if (this.currentCharacter == '*') {
 									isJavadoc = true;
 									star = true;
@@ -1422,6 +1414,7 @@
 									}
 								}
 								isUnicode = false;
+								previous = this.currentPosition;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 									&& (this.source[this.currentPosition] == 'u')) {
 									//-------------unicode traitement ------------
@@ -1440,6 +1433,7 @@
 									isJavadoc = false;
 								}
 								//loop until end of comment */
+								int firstTag = 0;
 								while ((this.currentCharacter != '/') || (!star)) {
 									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
 										checkNonExternalizedString();
@@ -1453,8 +1447,20 @@
 											this.currentLine = null;
 										}
 									}
-									star = this.currentCharacter == '*';
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0) {
+												firstTag = previous;
+											}
+											// fall through default case to set star to false
+										default:
+											star = false;
+									}
 									//get next char
+									previous = this.currentPosition;
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 										&& (this.source[this.currentPosition] == 'u')) {
 										//-------------unicode traitement ------------
@@ -1471,6 +1477,7 @@
 								}
 								int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK;
 								recordComment(token);
+								this.commentTagStarts[this.commentPtr] = firstTag;
 								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
 								if (this.tokenizeComments) {
 									/*
@@ -1497,7 +1504,37 @@
 					throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
 
 				default :
-					if (Character.isJavaIdentifierStart(this.currentCharacter))
+					char c = this.currentCharacter;
+					if (c < MAX_OBVIOUS) {
+						switch (ObviousIdentCharNatures[c]) {
+							case C_LETTER :
+								return scanIdentifierOrKeyword();
+							case C_DIGIT :
+								return scanNumber(false);
+						}
+					}
+					boolean isJavaIdStart;
+					if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						// Unicode 4 detection
+						char low = (char) getNextChar();
+						if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+							// illegal low surrogate
+							throw new InvalidInputException(INVALID_LOW_SURROGATE);
+						}
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
+					}
+					else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+					} else {
+						isJavaIdStart = Character.isJavaIdentifierStart(c);
+					}
+					if (isJavaIdStart)
 						return scanIdentifierOrKeyword();
 					if (isDigit(this.currentCharacter)) {
 						return scanNumber(false);
@@ -1516,7 +1553,7 @@
 	}
 	return TokenNameEOF;
 }
-public final void getNextUnicodeChar()
+public void getNextUnicodeChar()
 	throws InvalidInputException {
 	//VOID
 	//handle the case of unicode.
@@ -1543,16 +1580,15 @@
 			|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
 			|| c4 < 0){
 			throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-		} else {
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 		}
+		this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+		//need the unicode buffer
+		if (this.withoutUnicodePtr == 0) {
+			//buffer all the entries that have been left aside....
+			unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
+		}
+		//fill the buffer with the char
+		unicodeStore();
 		this.unicodeAsBackSlash = this.currentCharacter == '\\';
 	} catch (ArrayIndexOutOfBoundsException e) {
 		this.currentPosition--;
@@ -1563,6 +1599,7 @@
 public char[] getSource(){
 	return this.source;
 }
+// TODO (philippe) should simply switch on character
 protected boolean isDigit(char c) throws InvalidInputException {
 	if (Character.isDigit(c)) {
 		switch(c) {
@@ -1583,8 +1620,6 @@
 		return false;
 	}
 }
-/* Tokenize a method body, assuming that curly brackets are properly balanced.
- */
 public final void jumpOverMethodBody() {
 
 	this.wasAcr = false;
@@ -1607,21 +1642,34 @@
 			} while (isWhiteSpace);
 
 			// -------consume token until } is found---------
-			switch (this.currentCharacter) {
+			NextToken: switch (this.currentCharacter) {
 				case '{' :
 					found++;
-					break;
+					break NextToken;
 				case '}' :
 					found--;
 					if (found == 0)
 						return;
-					break;
+					break NextToken;
 				case '\'' :
 					{
 						boolean test;
 						test = getNextChar('\\');
 						if (test) {
 							try {
+								if (this.unicodeAsBackSlash) {
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+									} else {
+										if (this.withoutUnicodePtr != 0) {
+											unicodeStore();
+										}
+									}
+								} else {
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
 								scanEscapeCharacter();
 							} catch (InvalidInputException ex) {
 								// ignore
@@ -1630,11 +1678,11 @@
 							try { // consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										unicodeStoreAt(++this.withoutUnicodePtr);
+										unicodeStore();
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1642,18 +1690,18 @@
 							}
 						}
 						getNextChar('\'');
-						break;
+						break NextToken;
 					}
 				case '"' :
 					try {
 						try { // consume next character
 							this.unicodeAsBackSlash = false;
 							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-								&& (this.source[this.currentPosition] == 'u')) {
+									&& (this.source[this.currentPosition] == 'u')) {
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-								    unicodeStoreAt(++this.withoutUnicodePtr);
+								    unicodeStore();
 								}
 							}
 						} catch (InvalidInputException ex) {
@@ -1662,13 +1710,26 @@
 						while (this.currentCharacter != '"') {
 							if (this.currentCharacter == '\r'){
 								if (this.source[this.currentPosition] == '\n') this.currentPosition++;
-								break; // the string cannot go further that the line
+								break NextToken; // the string cannot go further that the line
 							}
 							if (this.currentCharacter == '\n'){
 								break; // the string cannot go further that the line
 							}
 							if (this.currentCharacter == '\\') {
 								try {
+									if (this.unicodeAsBackSlash) {
+										// consume next character
+										this.unicodeAsBackSlash = false;
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											getNextUnicodeChar();
+										} else {
+											if (this.withoutUnicodePtr != 0) {
+												unicodeStore();
+											}
+										}
+									} else {
+										this.currentCharacter = this.source[this.currentPosition++];
+									}
 									scanEscapeCharacter();
 								} catch (InvalidInputException ex) {
 									// ignore
@@ -1677,11 +1738,11 @@
 							try { // consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										unicodeStoreAt(++this.withoutUnicodePtr);
+										unicodeStore();
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1691,7 +1752,7 @@
 					} catch (IndexOutOfBoundsException e) {
 						return;
 					}
-					break;
+					break NextToken;
 				case '/' :
 					{
 						int test;
@@ -1700,26 +1761,8 @@
 								this.lastCommentLinePosition = this.currentPosition;
 								//get the next char 
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
-									//-------------unicode traitement ------------
-									int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-									this.currentPosition++;
-									while (this.source[this.currentPosition] == 'u') {
-										this.currentPosition++;
-									}
-									if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c1 < 0
-										|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c2 < 0
-										|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c3 < 0
-										|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c4 < 0) { //error don't care of the value
-										this.currentCharacter = 'A';
-									} //something different from \n and \r
-									else {
-										this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-									}
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
 								}
 								//handle the \\u case manually into comment
 								if (this.currentCharacter == '\\') {
@@ -1732,27 +1775,9 @@
 									//get the next char 
 									isUnicode = false;
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-										&& (this.source[this.currentPosition] == 'u')) {
+											&& (this.source[this.currentPosition] == 'u')) {
 										isUnicode = true;
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										this.currentPosition++;
-										while (this.source[this.currentPosition] == 'u') {
-											this.currentPosition++;
-										}
-										if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c4 < 0) { //error don't care of the value
-											this.currentCharacter = 'A';
-										} //something different from \n and \r
-										else {
-											this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
+										getNextUnicodeChar();
 									}
 									//handle the \\u case manually into comment
 									if (this.currentCharacter == '\\') {
@@ -1769,32 +1794,9 @@
 										this.currentPosition++;
 										this.currentCharacter = '\n';
 								   	} else if ((this.source[this.currentPosition] == '\\')
-										&& (this.source[this.currentPosition + 1] == 'u')) {
+											&& (this.source[this.currentPosition + 1] == 'u')) {
 										isUnicode = true;
-										char unicodeChar;
-										int index = this.currentPosition + 1;
-										index++;
-										while (this.source[index] == 'u') {
-											index++;
-										}
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										if ((c1 = Character.getNumericValue(this.source[index++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[index++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[index++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[index++])) > 15
-											|| c4 < 0) { //error don't care of the value
-											unicodeChar = 'A';
-										} else {
-											unicodeChar = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
-										if (unicodeChar == '\n') {
-											this.currentPosition = index;
-											this.currentCharacter = '\n';
-										}
+										getNextUnicodeChar();
 									}
 							   	}
 								recordComment(TokenNameCOMMENT_LINE);
@@ -1814,23 +1816,24 @@
 									this.currentPosition++; 
 								}
 							}
-							break;
+							break NextToken;
 						}
 						if (test > 0) { //traditional and javadoc comment
 							boolean isJavadoc = false;
 							try { //get the next char
 								boolean star = false;
+								int previous;
 								boolean isUnicode = false;
 								// consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 									isUnicode = true;
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-    								    unicodeStoreAt(++this.withoutUnicodePtr);
+    								    unicodeStore();
 									}
 								}
 	
@@ -1850,9 +1853,9 @@
 									}
 								}
 								isUnicode = false;
+								previous = this.currentPosition;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
-									//-------------unicode traitement ------------
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 									isUnicode = true;
 								} else {
@@ -1868,6 +1871,7 @@
 									isJavadoc = false;
 								}
 								//loop until end of comment */
+								int firstTag = 0;
 								while ((this.currentCharacter != '/') || (!star)) {
 									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
 										if (this.recordLineSeparator) {
@@ -1880,11 +1884,22 @@
 											this.currentLine = null;
 										}
 									}
-									star = this.currentCharacter == '*';
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0) {
+												firstTag = previous;
+											}
+											// fall through default case to set star to false
+										default:
+											star = false;
+									}
 									//get next char
+									previous = this.currentPosition;
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-										&& (this.source[this.currentPosition] == 'u')) {
-										//-------------unicode traitement ------------
+											&& (this.source[this.currentPosition] == 'u')) {
 										getNextUnicodeChar();
 										isUnicode = true;
 									} else {
@@ -1897,26 +1912,59 @@
 									} //jump over the \\
 								}
 								recordComment(isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK);
+								this.commentTagStarts[this.commentPtr] = firstTag;
 							} catch (IndexOutOfBoundsException e) {
 								return;
 							}
-							break;
+							break NextToken;
 						}
-						break;
+						break NextToken;
 					}
 
 				default :
-					if (Character.isJavaIdentifierStart(this.currentCharacter)) {
-						scanIdentifierOrKeyword();
-						break;
-					}
-					if (isDigit(this.currentCharacter)) {
-						try {
+					try {
+						char c = this.currentCharacter;
+						if (c < MAX_OBVIOUS) {
+							switch (ObviousIdentCharNatures[c]) {
+								case C_LETTER :
+									scanIdentifierOrKeyword();
+									break NextToken;
+								case C_DIGIT :
+									scanNumber(false);
+									break NextToken;
+							}
+						}
+						boolean isJavaIdStart;
+						if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+							if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+								throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+							}
+							// Unicode 4 detection
+							char low = (char) getNextChar();
+							if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+								// illegal low surrogate
+								throw new InvalidInputException(INVALID_LOW_SURROGATE);
+							}
+							isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
+						}
+						else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+							if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+								throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+							}
+							throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+						} else {
+							isJavaIdStart = Character.isJavaIdentifierStart(c);
+						}
+						if (isJavaIdStart) {
+							scanIdentifierOrKeyword();
+							break NextToken;
+						}
+						if (isDigit(this.currentCharacter)) {
 							scanNumber(false);
-						} catch (InvalidInputException ex) {
- 							// ignore
- 						}
-						break;
+							break NextToken;
+						}						
+					} catch (InvalidInputException ex) {
+						// ignore
 					}
 			}
 		}
@@ -1937,30 +1985,8 @@
 
 	try {
 		this.wasAcr = false;
-		int c1, c2, c3, c4;
-		int unicodeSize = 6;
-		this.currentPosition++;
-		while (this.source[this.currentPosition] == 'u') {
-			this.currentPosition++;
-			unicodeSize++;
-		}
-
-		if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-			|| c1 < 0)
-			|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-			|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-			|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-			throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-		}
-
-		this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-		if (CharOperation.isWhitespace(this.currentCharacter))
-			return true;
-
-		//buffer the new char which is not a white space
-		unicodeStoreAt(++this.withoutUnicodePtr);
-		//this.withoutUnicodePtr == 1 is true here
-		return false;
+		getNextUnicodeChar();
+		return CharOperation.isWhitespace(this.currentCharacter);
 	} catch (IndexOutOfBoundsException e){
 		this.currentPosition--;
 		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
@@ -2032,10 +2058,10 @@
 final char[] optimizedCurrentTokenSource2() {
 	//try to return the same char[] build only once
 
-	char c0, c1;
-	int hash = 
-		(((c0 = this.source[this.startPosition]) << 6) + (c1 = this.source[this.startPosition + 1]))
-			% TableSize; 
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0 , c1;
+	int hash = (((c0=src[start]) << 6) + (c1=src[start+1])) % TableSize; 
 	char[][] table = this.charArray_length[0][hash];
 	int i = newEntry2;
 	while (++i < InternalTableSize) {
@@ -2054,19 +2080,18 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1});
-	newEntry2 = max;
-	return r;
+	System.arraycopy(src, start, r= new char[2], 0, 2);
+	//newIdentCount++;
+	return table[newEntry2 = max] = r; //(r = new char[] {c0, c1});
 }
 final char[] optimizedCurrentTokenSource3() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2;
-	int hash = 
-		(((c0 = this.source[this.startPosition]) << 12)
-			+ ((c1 = this.source[this.startPosition + 1]) << 6)
-			+ (c2 = this.source[this.startPosition + 2]))
-			% TableSize; 
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1=src[start+1], c2;
+	int hash = (((c0=src[start])<< 6) + (c2=src[start+2])) % TableSize; 
+//	int hash = ((c0 << 12) + (c1<< 6) + c2) % TableSize; 
 	char[][] table = this.charArray_length[1][hash];
 	int i = newEntry3;
 	while (++i < InternalTableSize) {
@@ -2085,21 +2110,19 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2});
-	newEntry3 = max;
-	return r;
+	System.arraycopy(src, start, r= new char[3], 0, 3);
+	//newIdentCount++;
+	return table[newEntry3 = max] = r; //(r = new char[] {c0, c1, c2});
 }
 final char[] optimizedCurrentTokenSource4() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2, c3;
-	long hash = 
-		((((long) (c0 = this.source[this.startPosition])) << 18)
-			+ ((c1 = this.source[this.startPosition + 1]) << 12)
-			+ ((c2 = this.source[this.startPosition + 2]) << 6)
-			+ (c3 = this.source[this.startPosition + 3]))
-			% TableSize; 
-	char[][] table = this.charArray_length[2][(int) hash];
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3];
+	int hash = (((c0=src[start]) << 6) + (c2=src[start+2])) % TableSize;
+//	int hash = (int) (((((long) c0) << 18) + (c1 << 12) + (c2 << 6) + c3) % TableSize); 
+	char[][] table = this.charArray_length[2][hash];
 	int i = newEntry4;
 	while (++i < InternalTableSize) {
 		char[] charArray = table[i];
@@ -2123,23 +2146,19 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2, c3});
-	newEntry4 = max;
-	return r;
-	
+	System.arraycopy(src, start, r= new char[4], 0, 4);
+	//newIdentCount++;
+	return table[newEntry4 = max] = r; //(r = new char[] {c0, c1, c2, c3});
 }
 final char[] optimizedCurrentTokenSource5() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2, c3, c4;
-	long hash = 
-		((((long) (c0 = this.source[this.startPosition])) << 24)
-			+ (((long) (c1 = this.source[this.startPosition + 1])) << 18)
-			+ ((c2 = this.source[this.startPosition + 2]) << 12)
-			+ ((c3 = this.source[this.startPosition + 3]) << 6)
-			+ (c4 = this.source[this.startPosition + 4]))
-			% TableSize; 
-	char[][] table = this.charArray_length[3][(int) hash];
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4;
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int) (((((long) c0) << 24) + (((long) c1) << 18) + (c2 << 12) + (c3 << 6) + c4) % TableSize); 
+	char[][] table = this.charArray_length[3][hash];
 	int i = newEntry5;
 	while (++i < InternalTableSize) {
 		char[] charArray = table[i];
@@ -2165,24 +2184,19 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2, c3, c4});
-	newEntry5 = max;
-	return r;
-		
+	System.arraycopy(src, start, r= new char[5], 0, 5);
+	//newIdentCount++;
+	return table[newEntry5 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4});
 }
 final char[] optimizedCurrentTokenSource6() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2, c3, c4, c5;
-	long hash = 
-		((((long) (c0 = this.source[this.startPosition])) << 32)
-			+ (((long) (c1 = this.source[this.startPosition + 1])) << 24)
-			+ (((long) (c2 = this.source[this.startPosition + 2])) << 18)
-			+ ((c3 = this.source[this.startPosition + 3]) << 12)
-			+ ((c4 = this.source[this.startPosition + 4]) << 6)
-			+ (c5 = this.source[this.startPosition + 5]))
-			% TableSize; 
-	char[][] table = this.charArray_length[4][(int) hash];
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4, c5 = src[start+5];
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int)(((((long) c0) << 32) + (((long) c1) << 24) + (((long) c2) << 18) + (c3 << 12) + (c4 << 6) + c5) % TableSize); 
+	char[][] table = this.charArray_length[4][hash];
 	int i = newEntry6;
 	while (++i < InternalTableSize) {
 		char[] charArray = table[i];
@@ -2210,10 +2224,11 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2, c3, c4, c5});
-	newEntry6 = max;
-	return r;	
+	System.arraycopy(src, start, r= new char[6], 0, 6);
+	//newIdentCount++;
+	return table[newEntry6 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4, c5});
 }
+
 protected void parseTags(NLSLine line) {
 	String s = new String(getCurrentTokenSource());
 	int pos = s.indexOf(TAG_PREFIX);
@@ -2329,6 +2344,7 @@
 		}
 	}
 }
+
 public void recordComment(int token) {
 	// compute position
 	int stopPosition = this.currentPosition;
@@ -2344,9 +2360,10 @@
 	// a new comment is recorded
 	int length = this.commentStops.length;
 	if (++this.commentPtr >=  length) {
-		System.arraycopy(this.commentStops, 0, this.commentStops = new int[length + 30], 0, length);
-		//grows the positions buffers too
-		System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[length + 30], 0, length);
+		int newLength = length + COMMENT_ARRAYS_SIZE*10;
+		System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length);
+		System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length);
+		System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length);
 	}
 	this.commentStops[this.commentPtr] = stopPosition;
 	this.commentStarts[this.commentPtr] = this.startPosition;
@@ -2364,7 +2381,11 @@
 
 	this.diet = false;
 	this.initialPosition = this.startPosition = this.currentPosition = begin;
-	this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+	if (this.source != null && this.source.length < end) {
+		this.eofPosition = this.source.length;
+	} else {
+		this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+	}
 	this.commentPtr = -1; // reset comment stack
 	this.foundTaskCount = 0;
 	
@@ -2377,19 +2398,6 @@
 public final void scanEscapeCharacter() throws InvalidInputException {
 	// the string with "\\u" is a legal string of two chars \ and u
 	//thus we use a direct access to the source (for regular cases).
-
-	if (this.unicodeAsBackSlash) {
-		// consume next character
-		this.unicodeAsBackSlash = false;
-		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
-			getNextUnicodeChar();
-		} else {
-			if (this.withoutUnicodePtr != 0) {
-				unicodeStoreAt(++this.withoutUnicodePtr);
-			}
-		}
-	} else
-		this.currentCharacter = this.source[this.currentPosition++];
 	switch (this.currentCharacter) {
 		case 'b' :
 			this.currentCharacter = '\b';
@@ -2464,11 +2472,45 @@
 	//dispatch on the second char 
 	this.useAssertAsAnIndentifier = false;
 	this.useEnumAsAnIndentifier = false;
-	while (getNextCharAsJavaIdentifierPart()){/*empty*/}
 
+	char[] src = this.source;
+	identLoop: {
+		int pos, srcLength = this.source.length;
+		while (true) {
+			if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
+				break identLoop;
+			char c = src[pos];
+			if (c < MAX_OBVIOUS) {
+				switch (ObviousIdentCharNatures[c]) {
+					case C_LETTER :
+					case C_DIGIT :
+		               if (this.withoutUnicodePtr != 0) {
+							this.currentCharacter = c;
+							unicodeStore();
+						}
+						this.currentPosition++;
+						break;						
+						
+					case C_SEPARATOR :
+					case C_SPACE :
+						this.currentCharacter = c;
+						break identLoop;	
+
+					default:
+						//System.out.println("slow<=128:  "+ c);						
+						while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+						break identLoop;						
+				}
+			} else {
+				//System.out.println("slow>>128:  "+ c);						
+				while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+				break identLoop;						
+			}
+		}
+	}
+	
 	int index, length;
 	char[] data;
-	char firstLetter;
 	if (this.withoutUnicodePtr == 0)
 
 		//quick test on length == 1 but not on length > 12 while most identifier
@@ -2487,8 +2529,8 @@
 		index = 1;
 	}
 
-	firstLetter = data[index];
-	switch (firstLetter) {
+
+	switch (data[index]) {
 
 		case 'a' : 
 			switch(length) {
@@ -2583,7 +2625,7 @@
 							&& (data[++index] == 'n')
 							&& (data[++index] == 's')
 							&& (data[++index] == 't'))
-							return TokenNameERROR; //const is not used in java ???????
+							return TokenNameconst; //const is not used in java ???????
 						else
 							return TokenNameIdentifier;
 				case 8 :
@@ -2711,7 +2753,7 @@
 				if ((data[++index] == 'o')
 					&& (data[++index] == 't')
 					&& (data[++index] == 'o')) {
-					return TokenNameERROR;
+					return TokenNamegoto;
 				}
 			} //no goto in java are allowed, so why java removes this keyword ???
 			return TokenNameIdentifier;
@@ -3037,6 +3079,8 @@
 			return TokenNameIdentifier;
 	}
 }
+
+
 public int scanNumber(boolean dotPrefix) throws InvalidInputException {
 
 	//when entering this method the currentCharacter is the first
@@ -3056,11 +3100,13 @@
 				return TokenNameLongLiteral;
 			} else if (getNextChar('.')) {
 				if (this.sourceLevel < ClassFileConstants.JDK1_5) {
-					// if we are in source level < 1.5, we report an integer literal
+					if (end == start) {
+						throw new InvalidInputException(INVALID_HEXA);
+					}
 					this.currentPosition = end;
 					return TokenNameIntegerLiteral;
 				}
-				// hexadeciman floating point literal
+				// hexadecimal floating point literal
 				// read decimal part
 				boolean hasNoDigitsBeforeDot = end == start;
 				start = this.currentPosition;
@@ -3077,7 +3123,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							unicodeStoreAt(++this.withoutUnicodePtr);
+							unicodeStore();
 						}
 					}
 
@@ -3089,7 +3135,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 					}
@@ -3122,7 +3168,7 @@
 					getNextUnicodeChar();
 				} else {
 					if (this.withoutUnicodePtr != 0) {
-						unicodeStoreAt(++this.withoutUnicodePtr);
+						unicodeStore();
 					}
 				}
 
@@ -3134,7 +3180,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							unicodeStoreAt(++this.withoutUnicodePtr);
+							unicodeStore();
 						}
 					}
 				}
@@ -3185,7 +3231,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							unicodeStoreAt(++this.withoutUnicodePtr);
+							unicodeStore();
 						}
 					}
 
@@ -3197,7 +3243,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 					}
@@ -3237,7 +3283,7 @@
 			getNextUnicodeChar();
 		} else {
 			if (this.withoutUnicodePtr != 0) {
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			}
 		}
 
@@ -3249,7 +3295,7 @@
 				getNextUnicodeChar();
 			} else {
 				if (this.withoutUnicodePtr != 0) {
-					unicodeStoreAt(++this.withoutUnicodePtr);
+					unicodeStore();
 				}
 			}
 		}
@@ -3327,7 +3373,6 @@
 		this.linePtr = lineSeparatorPositions.length - 1;
 	}
 }
-
 public String toString() {
 	if (this.startPosition == this.source.length)
 		return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
@@ -3573,6 +3618,8 @@
 			return "="; //$NON-NLS-1$
 		case TokenNameEOF :
 			return "EOF"; //$NON-NLS-1$
+		case TokenNameWHITESPACE :
+			return "white_space(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 		default :
 			return "not-a-token"; //$NON-NLS-1$
 	}
@@ -3586,7 +3633,8 @@
     }
 	System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);    
 }
-public void unicodeStoreAt(int pos) {
+public void unicodeStore() {
+	int pos = ++this.withoutUnicodePtr;
     if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
     int length = this.withoutUnicodeBuffer.length;
     if (pos == length) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
new file mode 100644
index 0000000..1a25efe
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.io.DataInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class ScannerHelper {
+	public final static int Bit1 = 0x1;
+	public final static int Bit2 = 0x2;
+	public final static int Bit3 = 0x4;
+	public final static int Bit4 = 0x8;
+	public final static int Bit5 = 0x10;
+	public final static int Bit6 = 0x20;
+	public final static int Bit7 = 0x40;
+	public final static int Bit8 = 0x80;
+	public final static int Bit9 = 0x100;
+	public final static int Bit10= 0x200;
+	public final static int Bit11 = 0x400;
+	public final static int Bit12 = 0x800;
+	public final static int Bit13 = 0x1000;
+	public final static int Bit14 = 0x2000;
+	public final static int Bit15 = 0x4000;
+	public final static int Bit16 = 0x8000;
+	public final static int Bit17 = 0x10000;
+	public final static int Bit18 = 0x20000; 
+	public final static int Bit19 = 0x40000; 
+	public final static int Bit20 = 0x80000; 
+	public final static int Bit21 = 0x100000; 		
+	public final static int Bit22 = 0x200000;
+	public final static int Bit23 = 0x400000;
+	public final static int Bit24 = 0x800000;
+	public final static int Bit25 = 0x1000000;
+	public final static int Bit26 = 0x2000000;
+	public final static int Bit27 = 0x4000000;
+	public final static int Bit28 = 0x8000000;
+	public final static int Bit29 = 0x10000000;
+	public final static int Bit30 = 0x20000000;
+	public final static int Bit31 = 0x40000000;
+	public final static int Bit32 = 0x80000000;
+	public final static long Bit33 = 0x100000000L;
+	public final static long Bit34 = 0x200000000L;
+	public final static long Bit35 = 0x400000000L;
+	public final static long Bit36 = 0x800000000L;
+	public final static long Bit37 = 0x1000000000L;
+	public final static long Bit38 = 0x2000000000L;
+	public final static long Bit39 = 0x4000000000L;
+	public final static long Bit40 = 0x8000000000L;
+	public final static long Bit41 = 0x10000000000L;
+	public final static long Bit42 = 0x20000000000L;
+	public final static long Bit43 = 0x40000000000L;
+	public final static long Bit44 = 0x80000000000L;
+	public final static long Bit45 = 0x100000000000L;
+	public final static long Bit46 = 0x200000000000L;
+	public final static long Bit47 = 0x400000000000L;
+	public final static long Bit48 = 0x800000000000L;
+	public final static long Bit49 = 0x1000000000000L;
+	public final static long Bit50 = 0x2000000000000L;
+	public final static long Bit51 = 0x4000000000000L;
+	public final static long Bit52 = 0x8000000000000L;
+	public final static long Bit53 = 0x10000000000000L;
+	public final static long Bit54 = 0x20000000000000L;
+	public final static long Bit55 = 0x40000000000000L;
+	public final static long Bit56 = 0x80000000000000L;
+	public final static long Bit57 = 0x100000000000000L;
+	public final static long Bit58 = 0x200000000000000L;
+	public final static long Bit59 = 0x400000000000000L;
+	public final static long Bit60 = 0x800000000000000L;
+	public final static long Bit61 = 0x1000000000000000L;
+	public final static long Bit62 = 0x2000000000000000L;
+	public final static long Bit63 = 0x4000000000000000L;
+	public final static long Bit64 = 0x8000000000000000L;
+	public final static long[] Bits = { Bit1, Bit2, Bit3, Bit4, Bit5, Bit6,
+			Bit7, Bit8, Bit9, Bit10, Bit11, Bit12, Bit13, Bit14, Bit15, Bit16,
+			Bit17, Bit18, Bit19, Bit20, Bit21, Bit22, Bit23, Bit24, Bit25,
+			Bit26, Bit27, Bit28, Bit29, Bit30, Bit31, Bit32, Bit33, Bit34,
+			Bit35, Bit36, Bit37, Bit38, Bit39, Bit40, Bit41, Bit42, Bit43,
+			Bit44, Bit45, Bit46, Bit47, Bit48, Bit49, Bit50, Bit51, Bit52,
+			Bit53, Bit54, Bit55, Bit56, Bit57, Bit58, Bit59, Bit60, Bit61,
+			Bit62, Bit63, Bit64,
+	};
+
+	private static final int START_INDEX = 0;
+	private static final int PART_INDEX = 1;
+
+	private static long[][][] Tables;
+
+	static {
+		Tables = new long[2][][];
+		Tables[START_INDEX] = new long[2][];
+		Tables[PART_INDEX] = new long[3][];
+		try {
+			DataInputStream inputStream = new DataInputStream(ScannerHelper.class.getResourceAsStream("start1.rsc")); //$NON-NLS-1$
+			long[] readValues = new long[1024];
+			for (int i = 0; i < 1024; i++) {
+				readValues[i] = inputStream.readLong();
+			}
+			inputStream.close();
+			Tables[START_INDEX][0] = readValues;
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		try {
+			DataInputStream inputStream = new DataInputStream(ScannerHelper.class.getResourceAsStream("start2.rsc")); //$NON-NLS-1$
+			long[] readValues = new long[1024];
+			for (int i = 0; i < 1024; i++) {
+				readValues[i] = inputStream.readLong();
+			}
+			inputStream.close();
+			Tables[START_INDEX][1] = readValues;
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		try {
+			DataInputStream inputStream = new DataInputStream(ScannerHelper.class.getResourceAsStream("part1.rsc")); //$NON-NLS-1$
+			long[] readValues = new long[1024];
+			for (int i = 0; i < 1024; i++) {
+				readValues[i] = inputStream.readLong();
+			}
+			inputStream.close();
+			Tables[PART_INDEX][0] = readValues;
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		try {
+			DataInputStream inputStream = new DataInputStream(ScannerHelper.class.getResourceAsStream("part2.rsc")); //$NON-NLS-1$
+			long[] readValues = new long[1024];
+			for (int i = 0; i < 1024; i++) {
+				readValues[i] = inputStream.readLong();
+			}
+			inputStream.close();
+			Tables[PART_INDEX][1] = readValues;
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		try {
+			DataInputStream inputStream = new DataInputStream(ScannerHelper.class.getResourceAsStream("part14.rsc")); //$NON-NLS-1$
+			long[] readValues = new long[1024];
+			for (int i = 0; i < 1024; i++) {
+				readValues[i] = inputStream.readLong();
+			}
+			inputStream.close();
+			Tables[PART_INDEX][2] = readValues;
+		} catch (FileNotFoundException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private final static boolean isBitSet(long[] values, int i) {
+		try {
+			return (values[i / 64] & Bits[i % 64]) != 0;
+		} catch (NullPointerException e) {
+			return false;
+		}
+	}
+
+	public static boolean isJavaIdentifierPart(char high, char low) {
+		int codePoint = toCodePoint(high, low);
+		switch((codePoint & 0x1F0000) >> 16) {
+			case 0 :
+				return Character.isJavaIdentifierPart((char) codePoint);
+			case 1 :
+				return isBitSet(Tables[PART_INDEX][0], codePoint & 0xFFFF);
+			case 2 :
+				return isBitSet(Tables[PART_INDEX][1], codePoint & 0xFFFF);
+			case 14 :
+				return isBitSet(Tables[PART_INDEX][2], codePoint & 0xFFFF);
+		}
+		return false;
+	}
+	
+	public static boolean isJavaIdentifierStart(char high, char low) {
+		int codePoint = toCodePoint(high, low);
+		switch((codePoint & 0x1F0000) >> 16) {
+			case 0 :
+				return Character.isJavaIdentifierStart((char) codePoint);
+			case 1 :
+				return isBitSet(Tables[START_INDEX][0], codePoint & 0xFFFF);
+			case 2 :
+				return isBitSet(Tables[START_INDEX][1], codePoint & 0xFFFF);
+		}
+		return false;
+	}
+	
+	private static int toCodePoint(char high, char low) {	
+		return (high - Scanner.HIGH_SURROGATE_MIN_VALUE) * 0x400 + (low - Scanner.LOW_SURROGATE_MIN_VALUE) + 0x10000;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
index 45ea344..f161000 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -39,49 +39,51 @@
 		TokenNameboolean = 32,
 		TokenNamebreak = 75,
 		TokenNamebyte = 33,
-		TokenNamecase = 100,
-		TokenNamecatch = 101,
+		TokenNamecase = 101,
+		TokenNamecatch = 102,
 		TokenNamechar = 34,
 		TokenNameclass = 72,
 		TokenNamecontinue = 76,
-		TokenNamedefault = 96,
+		TokenNameconst = 108,
+		TokenNamedefault = 97,
 		TokenNamedo = 77,
 		TokenNamedouble = 35,
-		TokenNameelse = 102,
-		TokenNameenum = 103,
-		TokenNameextends = 97,
+		TokenNameelse = 103,
+		TokenNameenum = 98,
+		TokenNameextends = 99,
 		TokenNamefalse = 45,
 		TokenNamefinal = 57,
 		TokenNamefinally = 104,
 		TokenNamefloat = 36,
 		TokenNamefor = 78,
+		TokenNamegoto = 109,
 		TokenNameif = 79,
 		TokenNameimplements = 106,
-		TokenNameimport = 99,
+		TokenNameimport = 100,
 		TokenNameinstanceof = 15,
 		TokenNameint = 37,
-		TokenNameinterface = 80,
+		TokenNameinterface = 95,
 		TokenNamelong = 38,
 		TokenNamenative = 58,
 		TokenNamenew = 43,
 		TokenNamenull = 46,
-		TokenNamepackage = 98,
+		TokenNamepackage = 96,
 		TokenNameprivate = 59,
 		TokenNameprotected = 60,
 		TokenNamepublic = 61,
-		TokenNamereturn = 81,
+		TokenNamereturn = 80,
 		TokenNameshort = 39,
 		TokenNamestatic = 54,
 		TokenNamestrictfp = 62,
 		TokenNamesuper = 41,
-		TokenNameswitch = 82,
+		TokenNameswitch = 81,
 		TokenNamesynchronized = 55,
 		TokenNamethis = 42,
-		TokenNamethrow = 83,
+		TokenNamethrow = 82,
 		TokenNamethrows = 105,
 		TokenNametransient = 63,
 		TokenNametrue = 47,
-		TokenNametry = 84,
+		TokenNametry = 83,
 		TokenNamevoid = 40,
 		TokenNamevolatile = 64,
 		TokenNamewhile = 73,
@@ -100,34 +102,34 @@
 		TokenNameLEFT_SHIFT = 13,
 		TokenNameRIGHT_SHIFT = 8,
 		TokenNameUNSIGNED_RIGHT_SHIFT = 9,
-		TokenNamePLUS_EQUAL = 85,
-		TokenNameMINUS_EQUAL = 86,
-		TokenNameMULTIPLY_EQUAL = 87,
-		TokenNameDIVIDE_EQUAL = 88,
-		TokenNameAND_EQUAL = 89,
-		TokenNameOR_EQUAL = 90,
-		TokenNameXOR_EQUAL = 91,
-		TokenNameREMAINDER_EQUAL = 92,
-		TokenNameLEFT_SHIFT_EQUAL = 93,
-		TokenNameRIGHT_SHIFT_EQUAL = 94,
-		TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 95,
+		TokenNamePLUS_EQUAL = 84,
+		TokenNameMINUS_EQUAL = 85,
+		TokenNameMULTIPLY_EQUAL = 86,
+		TokenNameDIVIDE_EQUAL = 87,
+		TokenNameAND_EQUAL = 88,
+		TokenNameOR_EQUAL = 89,
+		TokenNameXOR_EQUAL = 90,
+		TokenNameREMAINDER_EQUAL = 91,
+		TokenNameLEFT_SHIFT_EQUAL = 92,
+		TokenNameRIGHT_SHIFT_EQUAL = 93,
+		TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 94,
 		TokenNameOR_OR = 25,
 		TokenNameAND_AND = 24,
 		TokenNamePLUS = 1,
 		TokenNameMINUS = 2,
-		TokenNameNOT = 68,
+		TokenNameNOT = 67,
 		TokenNameREMAINDER = 5,
 		TokenNameXOR = 21,
 		TokenNameAND = 20,
 		TokenNameMULTIPLY = 4,
 		TokenNameOR = 22,
-		TokenNameTWIDDLE = 69,
+		TokenNameTWIDDLE = 68,
 		TokenNameDIVIDE = 6,
 		TokenNameGREATER = 12,
 		TokenNameLESS = 7,
 		TokenNameLPAREN = 28,
 		TokenNameRPAREN = 29,
-		TokenNameLBRACE = 66,
+		TokenNameLBRACE = 69,
 		TokenNameRBRACE = 31,
 		TokenNameLBRACKET = 14,
 		TokenNameRBRACKET = 70,
@@ -139,6 +141,6 @@
 		TokenNameEQUAL = 71,
 		TokenNameAT = 44,
 		TokenNameELLIPSIS = 107,
-		TokenNameEOF = 67,
-		TokenNameERROR = 108;
-}
\ No newline at end of file
+		TokenNameEOF = 66,
+		TokenNameERROR = 110;
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
index 6c53f6a..5adee6f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java
index 3231806..3a0b577 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java
index 00b8d97..7e60727 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
index 8d6c3d9..f08b9bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
index 082965a..5de6e9b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
index d1a5283..924e7a3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
index 955f911..cf0228a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
index 9dc419e..35baf52 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
index ecfa021..d62f283 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
index d7836e5..9a18dbc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
index 64e337c..5e93598 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
index 6f199d2..1365bda 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
index cd31f71..856d1a0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
index 3b7856e..927a29e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
@@ -1 +1 @@
-ffFFFBBhAAA!FeAdAIB	JJB!BBBgGGP!H!!!!!,
\ No newline at end of file
+ggFFFEEhAAA!FfAeAIE	JJE!EEbGG_!H!!!!!,
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
index 3f73142..f088262 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
index c371c1c..79d03fc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
index 3a223d8..0a15223 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
index 8f173bd..920127b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
index 6246280..d383385 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
index f45b140..355084e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
index 188784f..0000f7c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
index 77673a0..c79761e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
index fcb83ba..5379910 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
index f8ca6a7..4a50e3d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part1.rsc
new file mode 100644
index 0000000..b7d2df1
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part14.rsc
new file mode 100644
index 0000000..14f9042
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part2.rsc
new file mode 100644
index 0000000..e37032a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/part2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties
index 6ddd4ae..dbe7834 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.properties
@@ -52,7 +52,6 @@
 ClassBodyDeclaration=ClassBodyDeclaration
 ClassBodyDeclarations=ClassBodyDeclarations
 ClassBodyDeclarationsopt=ClassBodyDeclarations
-ClassBodySimpleNameopt=ClassBody
 ClassBodyopt=ClassBody
 ClassDeclaration=ClassDeclaration
 ClassHeader=ClassHeader
@@ -96,8 +95,8 @@
 EnhancedForStatementHeader=EnhancedForStatementHeader
 EnhancedForStatementNoShortIf=EnhancedForStatementNoShortIf
 EnterAnonymousClassBody=EnterAnonymousClassBody
-EnterAnonymousClassBodySimpleName=EnterAnonymousClassBodySimpleName
 EnterCompilationUnit=EnterCompilationUnit
+EnterMemberValue=EnterMemberValue
 EnterVariable=EnterVariable
 EnumBody=EnumBody
 EnumBodyDeclarationsopt=EnumBodyDeclarationsopt
@@ -113,6 +112,7 @@
 EqualityExpression_NotName=Expression
 ExclusiveOrExpression=Expression
 ExclusiveOrExpression_NotName=Expression
+ExitMemberValue=ExitMemberValue
 ExitTryBlock=ExitTryBlock
 ExitVariableWithInitialization=ExitVariableWithInitialization
 ExitVariableWithoutInitialization=ExitVariableWithoutInitialization
@@ -170,8 +170,6 @@
 InternalCompilationUnit=CompilationUnit
 InvalidArrayInitializerAssignement=ArrayInitializerAssignement
 InvalidConstructorDeclaration=InvalidConstructorDeclaration
-InvalidInterfaceDeclaration=InvalidInterfaceDeclaration
-InvalidMethodDeclaration=InvalidMethodDeclaration
 LabeledStatement=LabeledStatement
 LabeledStatementNoShortIf=LabeledStatement
 Literal=Literal
@@ -208,6 +206,7 @@
 OnlyTypeArguments=TypeArguments
 OnlyTypeArgumentsForCastExpression=TypeArguments
 OpenBlock=OpenBlock
+PackageComment=PackageComment
 PackageDeclaration=PackageDeclaration
 PackageDeclarationName=PackageDeclarationName
 PostDecrementExpression=PostDecrementExpression
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/start1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/start1.rsc
new file mode 100644
index 0000000..bf7e5aa
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/start1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/start2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/start2.rsc
new file mode 100644
index 0000000..e37032a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/start2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java
index 88e143d..12668b4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java
index 7ab9b07..d9b937c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java
index 7d8a3c9..b10a8fe 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java
index 77e7a0f..ac792c5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
index 8ec8619..81efea4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java
@@ -1,22 +1,21 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.problem;
 
 import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
 public class DefaultProblem implements ProblemSeverities, IProblem {
 	
-	private static final String LINE_DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$
-		
 	private char[] fileName;
 	private int id;
 	private int startPosition, endPosition, line;
@@ -53,11 +52,11 @@
 		//sanity .....
 		if ((this.startPosition > this.endPosition)
 			|| ((this.startPosition < 0) && (this.endPosition < 0)))
-			return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
+			return Messages.problem_noSourceInformation; 
 
 		StringBuffer errorBuffer = new StringBuffer(" "); //$NON-NLS-1$
-		errorBuffer.append(Util.bind("problem.atLine", String.valueOf(this.line))); //$NON-NLS-1$
-		errorBuffer.append(LINE_DELIMITER).append("\t"); //$NON-NLS-1$
+		errorBuffer.append(Messages.bind(Messages.problem_atLine, String.valueOf(this.line))); 
+		errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$
 		
 		char c;
 		final char SPACE = '\u0020';
@@ -83,7 +82,7 @@
 		
 		// copy source
 		errorBuffer.append(unitSource, begin, end-begin+1);
-		errorBuffer.append(LINE_DELIMITER).append("\t"); //$NON-NLS-1$
+		errorBuffer.append(Util.LINE_SEPARATOR).append("\t"); //$NON-NLS-1$
 
 		// compute underline
 		for (int i = begin; i <this.startPosition; i++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
index 065c525..3a8221b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
index 5b334d2..4506aee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 41b4d5f..849818e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -1,15 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.problem;
 
+import java.text.MessageFormat;
+
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.*;
@@ -19,7 +21,7 @@
 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.parser.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 
 public class ProblemReporter extends ProblemHandler implements ProblemReasons {
 	
@@ -119,22 +121,6 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
-public void annotationCircularity(TypeBinding sourceType, TypeBinding otherType, TypeReference reference) {
-	if (sourceType == otherType)
-		this.handle(
-			IProblem.AnnotationCircularitySelfReference,
-			new String[] {new String(sourceType.readableName())},
-			new String[] {new String(sourceType.shortReadableName())},
-			reference.sourceStart,
-			reference.sourceEnd);
-	else
-		this.handle(
-			IProblem.AnnotationCircularity,
-			new String[] {new String(sourceType.readableName()), new String(otherType.readableName())},
-			new String[] {new String(sourceType.shortReadableName()), new String(otherType.shortReadableName())},
-			reference.sourceStart,
-			reference.sourceEnd);
-}
 public void annotationCannotOverrideMethod(MethodBinding overrideMethod, MethodBinding inheritedMethod) {
 	ASTNode location = overrideMethod.sourceMethod();
 	this.handle(
@@ -152,6 +138,22 @@
 		location.sourceStart,
 		location.sourceEnd);	
 }
+public void annotationCircularity(TypeBinding sourceType, TypeBinding otherType, TypeReference reference) {
+	if (sourceType == otherType)
+		this.handle(
+			IProblem.AnnotationCircularitySelfReference,
+			new String[] {new String(sourceType.readableName())},
+			new String[] {new String(sourceType.shortReadableName())},
+			reference.sourceStart,
+			reference.sourceEnd);
+	else
+		this.handle(
+			IProblem.AnnotationCircularity,
+			new String[] {new String(sourceType.readableName()), new String(otherType.readableName())},
+			new String[] {new String(sourceType.shortReadableName()), new String(otherType.shortReadableName())},
+			reference.sourceStart,
+			reference.sourceEnd);
+}
 public void annotationFieldNeedConstantInitialization(FieldDeclaration fieldDecl) {
 	String str = new String(fieldDecl.name);
 	this.handle(
@@ -201,6 +203,24 @@
 		typeDeclaration.sourceStart,
 		typeDeclaration.sourceEnd);
 }
+public void annotationTypeUsedAsSuperinterface(SourceTypeBinding type, TypeReference superInterfaceRef, ReferenceBinding superType) {
+	this.handle(
+		IProblem.AnnotationTypeUsedAsSuperInterface,
+		new String[] {new String(superType.readableName()), new String(type.sourceName())},
+		new String[] {new String(superType.shortReadableName()), new String(type.sourceName())},
+		superInterfaceRef.sourceStart,
+		superInterfaceRef.sourceEnd);
+}
+
+public void annotationValueMustBeAnnotation(TypeBinding annotationType, char[] name, Expression value, TypeBinding expectedType) {
+	String str = new String(name);
+	this.handle(
+		IProblem.AnnotationValueMustBeAnnotation,
+		new String[] { new String(annotationType.readableName()), str, new String(expectedType.readableName()),  },
+		new String[] { new String(annotationType.shortReadableName()), str, new String(expectedType.readableName()), },
+		value.sourceStart,
+		value.sourceEnd);
+}
 public void annotationValueMustBeClassLiteral(TypeBinding annotationType, char[] name, Expression value) {
 	String str = new String(name);
 	this.handle(
@@ -286,6 +306,14 @@
 		expression.sourceStart,
 		expression.sourceEnd);
 }
+public void boundCannotBeArray(ASTNode location, TypeBinding type) {
+	this.handle(
+		IProblem.BoundCannotBeArray,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
 public void boundHasConflictingArguments(ASTNode location, TypeBinding type) {
 	this.handle(
 		IProblem.BoundHasConflictingArguments,
@@ -294,9 +322,9 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
-public void boundsMustBeAnInterface(ASTNode location, TypeBinding type) {
+public void boundMustBeAnInterface(ASTNode location, TypeBinding type) {
 	this.handle(
-		IProblem.BoundsMustBeAnInterface,
+		IProblem.BoundMustBeAnInterface,
 		new String[] {new String(type.readableName())},
 		new String[] {new String(type.shortReadableName())},
 		location.sourceStart,
@@ -369,15 +397,6 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
-public void cannotDeclareLocalInterface(char[] interfaceName, int sourceStart, int sourceEnd) {
-	String[] arguments = new String[] {new String(interfaceName)};
-	this.handle(
-		IProblem.CannotDefineInterfaceInLocalType,
-		arguments,
-		arguments,
-		sourceStart,
-		sourceEnd);
-}
 public void cannotDefineDimensionsAndInitializer(ArrayAllocationExpression expresssion) {
 	this.handle(
 		IProblem.CannotDefineDimensionExpressionsWithInit,
@@ -423,6 +442,20 @@
 		typeRef.sourceStart,
 		typeRef.sourceEnd);
 }
+public void cannotInvokeSuperConstructorInEnum(ExplicitConstructorCall constructorCall, MethodBinding enumConstructor) {
+	this.handle(
+		IProblem.CannotInvokeSuperConstructorInEnum,
+		new String[] { 
+		        new String(enumConstructor.declaringClass.sourceName()),
+		        typesAsString(enumConstructor.isVarargs(), enumConstructor.parameters, false), 
+		 },
+		new String[] { 
+		        new String(enumConstructor.declaringClass.sourceName()),
+		        typesAsString(enumConstructor.isVarargs(), enumConstructor.parameters, true), 
+		 },
+		constructorCall.sourceStart,
+		constructorCall.sourceEnd);
+}
 public void cannotReferToNonFinalOuterLocal(LocalVariableBinding local, ASTNode location) {
 	String[] arguments =new String[]{ new String(local.readableName())};
 	this.handle(
@@ -456,6 +489,14 @@
 		exceptionType.sourceStart,
 		exceptionType.sourceEnd);
 }
+public void cannotUseQualifiedEnumConstantInCaseLabel(Reference reference, FieldBinding field) {
+	this.handle(
+			IProblem.IllegalQualifiedEnumConstantLabel,
+			new String[]{ String.valueOf(field.declaringClass.readableName()), String.valueOf(field.name) },
+			new String[]{ String.valueOf(field.declaringClass.shortReadableName()), String.valueOf(field.name) },
+			reference.sourceStart,
+			reference.sourceEnd);	
+}
 public void cannotUseSuperInCodeSnippet(int start, int end) {
 	this.handle(
 		IProblem.CannotUseSuperInCodeSnippet,
@@ -473,15 +514,6 @@
 		reference.sourceStart,
 		reference.sourceEnd);
 }
-public void cannotUseQualifiedEnumConstantInCaseLabel(QualifiedNameReference reference) {
-	String[] arguments = new String[]{ String.valueOf(reference.fieldBinding().name) };
-	this.handle(
-			IProblem.IllegalQualifiedEnumConstantLabel,
-			arguments,
-			arguments,
-			reference.sourceStart,
-			reference.sourceEnd);	
-}
 public void caseExpressionMustBeConstant(Expression expression) {
 	this.handle(
 		IProblem.NonConstantExpression,
@@ -614,6 +646,9 @@
 		case IProblem.FieldHidingField:
 			return this.options.getSeverity(CompilerOptions.FieldHiding);
 
+		case IProblem.TypeParameterHidingType:
+			return this.options.getSeverity(CompilerOptions.TypeParameterHiding);
+			
 		case IProblem.PossibleAccidentalBooleanAssignment:
 			return this.options.getSeverity(CompilerOptions.AccidentalBooleanAssign);
 
@@ -625,7 +660,6 @@
 			return this.options.getSeverity(CompilerOptions.UndocumentedEmptyBlock);
 			
 		case IProblem.UnnecessaryCast:
-		case IProblem.UnnecessaryArgumentCast:
 		case IProblem.UnnecessaryInstanceof:
 			return this.options.getSeverity(CompilerOptions.UnnecessaryTypeCheck);
 			
@@ -644,12 +678,22 @@
 
 		case IProblem.UnsafeRawConstructorInvocation:
 		case IProblem.UnsafeRawMethodInvocation:
-		case IProblem.UnsafeRawConversion:
+		case IProblem.UnsafeTypeConversion:
 		case IProblem.UnsafeRawFieldAssignment:
 		case IProblem.UnsafeGenericCast:
 		case IProblem.UnsafeReturnTypeOverride:
+		case IProblem.UnsafeRawGenericMethodInvocation:
+		case IProblem.UnsafeRawGenericConstructorInvocation:
 			return this.options.getSeverity(CompilerOptions.UncheckedTypeOperation);
 
+		case IProblem.MissingOverrideAnnotation:
+			return this.options.getSeverity(CompilerOptions.MissingOverrideAnnotation);
+			
+		case IProblem.FieldMissingDeprecatedAnnotation:
+		case IProblem.MethodMissingDeprecatedAnnotation:
+		case IProblem.TypeMissingDeprecatedAnnotation:
+			return this.options.getSeverity(CompilerOptions.MissingDeprecatedAnnotation);
+			
 		case IProblem.FinalBoundForTypeVariable:
 		    return this.options.getSeverity(CompilerOptions.FinalParameterBound);
 
@@ -659,6 +703,9 @@
 		case IProblem.ForbiddenReference:
 			return this.options.getSeverity(CompilerOptions.ForbiddenReference);
 
+		case IProblem.DiscouragedReference:
+			return this.options.getSeverity(CompilerOptions.DiscouragedReference);
+
 		case IProblem.MethodVarargsArgumentNeedCast :
 		case IProblem.ConstructorVarargsArgumentNeedCast :
 			return this.options.getSeverity(CompilerOptions.VarargsArgumentNeedCast);
@@ -671,6 +718,15 @@
 		case IProblem.UnboxingConversion :
 			return this.options.getSeverity(CompilerOptions.Autoboxing);
 
+		case IProblem.MissingEnumConstantCase :
+			return this.options.getSeverity(CompilerOptions.IncompleteEnumSwitch);
+			
+		case IProblem.VarargsConflict :
+			return Warning;
+			
+		case IProblem.AnnotationTypeUsedAsSuperInterface :
+			return this.options.getSeverity(CompilerOptions.AnnotationSuperInterface);
+			
 		/*
 		 * Javadoc syntax errors
 		 */
@@ -721,6 +777,16 @@
 		case IProblem.JavadocInheritedMethodHidesEnclosingName:
 		case IProblem.JavadocInheritedFieldHidesEnclosingName:
 		case IProblem.JavadocInheritedNameHidesEnclosingTypeName:
+		case IProblem.JavadocGenericMethodTypeArgumentMismatch:
+		case IProblem.JavadocNonGenericMethod:
+		case IProblem.JavadocIncorrectArityForParameterizedMethod:
+		case IProblem.JavadocParameterizedMethodArgumentTypeMismatch:
+		case IProblem.JavadocTypeArgumentsForRawGenericMethod:
+		case IProblem.JavadocGenericConstructorTypeArgumentMismatch:
+		case IProblem.JavadocNonGenericConstructor:
+		case IProblem.JavadocIncorrectArityForParameterizedConstructor:
+		case IProblem.JavadocParameterizedConstructorArgumentTypeMismatch:
+		case IProblem.JavadocTypeArgumentsForRawGenericConstructor:
 			if (this.options.docCommentSupport && this.options.reportInvalidJavadocTags) {
 				return this.options.getSeverity(CompilerOptions.InvalidJavadoc);
 			}
@@ -882,15 +948,6 @@
 			location.sourceEnd);
 	}
 }
-public void methodMustOverride(AbstractMethodDeclaration method) {
-	MethodBinding binding = method.binding;
-	this.handle(
-		IProblem.MethodMustOverride,
-		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false), new String(binding.declaringClass.readableName()), },
-		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true), new String(binding.declaringClass.shortReadableName()),},
-		method.sourceStart,
-		method.sourceEnd);
-}
 public void deprecatedType(TypeBinding type, ASTNode location) {
 	if (location == null) return; // 1G828DN - no type ref for synthetic arguments
 	this.handle(
@@ -900,6 +957,14 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
+public void disallowedTargetForAnnotation(Annotation annotation) {
+	this.handle(
+		IProblem.DisallowedTargetForAnnotation,
+		new String[] {new String(annotation.resolvedType.readableName())},
+		new String[] {new String(annotation.resolvedType.shortReadableName())},
+		annotation.sourceStart,
+		annotation.sourceEnd);
+}
 public void duplicateAnnotation(Annotation annotation) {
 	this.handle(
 		IProblem.DuplicateAnnotation,
@@ -917,14 +982,13 @@
 		memberValuePair.sourceStart,
 		memberValuePair.sourceEnd);
 }
-public void duplicateTargetInTargetAnnotation(TypeBinding annotationType, NameReference reference) {
-	String name = 	new String(reference.fieldBinding().name);
+public void duplicateBounds(ASTNode location, TypeBinding type) {
 	this.handle(
-		IProblem.DuplicateTargetInTargetAnnotation,
-		new String[] { name, new String(annotationType.readableName())},
-		new String[] {	name, new String(annotationType.shortReadableName())},
-		reference.sourceStart,
-		reference.sourceEnd);
+		IProblem.DuplicateBounds,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
 }
 public void duplicateCase(CaseStatement caseStatement) {
 	this.handle(
@@ -942,6 +1006,22 @@
 		statement.sourceStart,
 		statement.sourceEnd);
 }
+
+public void duplicateEnumSpecialMethod(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
+    MethodBinding method = methodDecl.binding;
+	this.handle(
+		IProblem.CannotDeclareEnumSpecialMethod,
+		new String[] {
+	        new String(methodDecl.selector),
+			new String(method.declaringClass.readableName()),
+			typesAsString(method.isVarargs(), method.parameters, false)},
+		new String[] {
+			new String(methodDecl.selector),
+			new String(method.declaringClass.shortReadableName()),
+			typesAsString(method.isVarargs(), method.parameters, true)},
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
 public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) {
 	this.handle(
 		IProblem.DuplicateField,
@@ -995,22 +1075,6 @@
 		location.sourceEnd);
 }
 
-public void duplicateEnumSpecialMethod(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
-    MethodBinding method = methodDecl.binding;
-	this.handle(
-		IProblem.CannotDeclareEnumSpecialMethod,
-		new String[] {
-	        new String(methodDecl.selector),
-			new String(method.declaringClass.readableName()),
-			typesAsString(method.isVarargs(), method.parameters, false)},
-		new String[] {
-			new String(methodDecl.selector),
-			new String(method.declaringClass.shortReadableName()),
-			typesAsString(method.isVarargs(), method.parameters, true)},
-		methodDecl.sourceStart,
-		methodDecl.sourceEnd);
-}
-
 public void duplicateMethodInType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
     MethodBinding method = methodDecl.binding;
     boolean duplicateErasure = false;
@@ -1124,6 +1188,15 @@
 		typeDecl.sourceStart,
 		typeDecl.sourceEnd);
 }
+public void duplicateTargetInTargetAnnotation(TypeBinding annotationType, NameReference reference) {
+	String name = 	new String(reference.fieldBinding().name);
+	this.handle(
+		IProblem.DuplicateTargetInTargetAnnotation,
+		new String[] { name, new String(annotationType.readableName())},
+		new String[] {	name, new String(annotationType.shortReadableName())},
+		reference.sourceStart,
+		reference.sourceEnd);
+}
 public void duplicateTypeParameterInType(TypeParameter typeParameter) {
 	this.handle(
 		IProblem.DuplicateTypeVariable,
@@ -1170,7 +1243,14 @@
 		method.sourceStart(),
 		method.sourceEnd());
 }
-
+public void enumSwitchCannotTargetField(Reference reference, FieldBinding field) {
+	this.handle(
+			IProblem.EnumSwitchCannotTargetField,
+			new String[]{ String.valueOf(field.declaringClass.readableName()), String.valueOf(field.name) },
+			new String[]{ String.valueOf(field.declaringClass.shortReadableName()), String.valueOf(field.name) },
+			reference.sourceStart,
+			reference.sourceEnd);	
+}
 public void errorNoMethodFor(MessageSend messageSend, TypeBinding recType, TypeBinding[] params) {
 	StringBuffer buffer = new StringBuffer();
 	StringBuffer shortBuffer = new StringBuffer();
@@ -1206,20 +1286,6 @@
 		reference.sourceStart,
 		reference.sourceEnd);
 }
-public void cannotInvokeSuperConstructorInEnum(ExplicitConstructorCall constructorCall, MethodBinding enumConstructor) {
-	this.handle(
-		IProblem.CannotInvokeSuperConstructorInEnum,
-		new String[] { 
-		        new String(enumConstructor.declaringClass.sourceName()),
-		        typesAsString(enumConstructor.isVarargs(), enumConstructor.parameters, false), 
-		 },
-		new String[] { 
-		        new String(enumConstructor.declaringClass.sourceName()),
-		        typesAsString(enumConstructor.isVarargs(), enumConstructor.parameters, true), 
-		 },
-		constructorCall.sourceStart,
-		constructorCall.sourceEnd);
-}
 public void expressionShouldBeAVariable(Expression expression) {
 	this.handle(
 		IProblem.ExpressionShouldBeAVariable,
@@ -1306,13 +1372,13 @@
 		typeRef.sourceStart,
 		typeRef.sourceEnd);
 }
-public void forbiddenReference(TypeBinding type, ASTNode location, String messageTemplate) {
-	if (location == null) return; 
+public void forbiddenReference(TypeBinding type, ASTNode location, String messageTemplate, int problemId) {
+	if (location == null) return;
 	// this problem has a message template extracted from the access restriction rule
 	this.handle(
-		IProblem.ForbiddenReference,
+		problemId,
 		new String[] { new String(type.readableName()) }, // distinct from msg arg for quickfix purpose
-		new String[] { Util.bindMessage(messageTemplate, new String[]{ new String(type.shortReadableName()) } ) },
+		new String[] { MessageFormat.format(messageTemplate, new String[]{ new String(type.shortReadableName())})},
 		location.sourceStart,
 		location.sourceEnd);
 }
@@ -1519,6 +1585,25 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
+public void illegalLocalTypeDeclaration(TypeDeclaration typeDeclaration) {
+	int problemID = 0;
+	if ((typeDeclaration.modifiers & IConstants.AccEnum) != 0) {
+		problemID = IProblem.CannotDefineEnumInLocalType;
+	} else if ((typeDeclaration.modifiers & IConstants.AccAnnotation) != 0) {
+		problemID = IProblem.CannotDefineAnnotationInLocalType;		
+	} else if ((typeDeclaration.modifiers & IConstants.AccInterface) != 0) {
+		problemID = IProblem.CannotDefineInterfaceInLocalType;		
+	}
+	if (problemID != 0) {
+		String[] arguments = new String[] {new String(typeDeclaration.name)};
+		this.handle(
+			problemID,
+			arguments,
+			arguments,
+			typeDeclaration.sourceStart,
+			typeDeclaration.sourceEnd);
+	}
+}
 public void illegalModifierCombinationFinalAbstractForClass(SourceTypeBinding type) {
 	String[] arguments = new String[] {new String(type.sourceName())};
 	this.handle(
@@ -1538,6 +1623,54 @@
 		fieldDecl.sourceStart,
 		fieldDecl.sourceEnd);
 }
+public void illegalModifierForAnnotationField(FieldDeclaration fieldDecl) {
+	String name = new String(fieldDecl.name);
+	this.handle(
+		IProblem.IllegalModifierForAnnotationField,
+		new String[] {
+			new String(fieldDecl.binding.declaringClass.readableName()),
+			name,
+		},		
+		new String[] {
+			new String(fieldDecl.binding.declaringClass.shortReadableName()),
+			name,
+		},		
+		fieldDecl.sourceStart,
+		fieldDecl.sourceEnd);
+}
+
+public void illegalModifierForAnnotationMember(AbstractMethodDeclaration methodDecl) {
+	this.handle(
+		IProblem.IllegalModifierForAnnotationMethod,
+		new String[] {
+			new String(methodDecl.binding.declaringClass.readableName()),
+			new String(methodDecl.selector),
+		},		
+		new String[] {
+			new String(methodDecl.binding.declaringClass.shortReadableName()),
+			new String(methodDecl.selector),
+		},		
+		methodDecl.sourceStart,
+		methodDecl.sourceEnd);
+}
+public void illegalModifierForAnnotationMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForAnnotationMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
+public void illegalModifierForAnnotationType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForAnnotationType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
 
 public void illegalModifierForClass(SourceTypeBinding type) {
 	String[] arguments = new String[] {new String(type.sourceName())};
@@ -1557,24 +1690,6 @@
 		type.sourceStart(),
 		type.sourceEnd());
 }
-public void illegalModifierForLocalEnum(SourceTypeBinding type) {
-	String[] arguments = new String[] {new String(type.sourceName())};
-	this.handle(
-		IProblem.IllegalModifierForLocalEnum,
-		arguments,
-		arguments,
-		type.sourceStart(),
-		type.sourceEnd());
-}
-public void illegalModifierForMemberEnum(SourceTypeBinding type) {
-	String[] arguments = new String[] {new String(type.sourceName())};
-	this.handle(
-		IProblem.IllegalModifierForMemberEnum,
-		arguments,
-		arguments,
-		type.sourceStart(),
-		type.sourceEnd());
-}
 public void illegalModifierForEnumConstant(ReferenceBinding type, FieldDeclaration fieldDecl) {
 	String[] arguments = new String[] {new String(fieldDecl.name)};
 	this.handle(
@@ -1584,6 +1699,14 @@
 		fieldDecl.sourceStart,
 		fieldDecl.sourceEnd);
 }
+public void illegalModifierForEnumConstructor(AbstractMethodDeclaration constructor) {
+	this.handle(
+		IProblem.IllegalModifierForEnumConstructor,
+		NoArgument,		
+		NoArgument,	
+		constructor.sourceStart,
+		constructor.sourceEnd);
+}
 public void illegalModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
 	String[] arguments = new String[] {new String(fieldDecl.name)};
 	this.handle(
@@ -1642,6 +1765,15 @@
 		type.sourceStart(),
 		type.sourceEnd());
 }
+public void illegalModifierForLocalEnum(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForLocalEnum,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
 public void illegalModifierForMemberClass(SourceTypeBinding type) {
 	String[] arguments = new String[] {new String(type.sourceName())};
 	this.handle(
@@ -1651,6 +1783,15 @@
 		type.sourceStart(),
 		type.sourceEnd());
 }
+public void illegalModifierForMemberEnum(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.IllegalModifierForMemberEnum,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
 public void illegalModifierForMemberInterface(SourceTypeBinding type) {
 	String[] arguments = new String[] {new String(type.sourceName())};
 	this.handle(
@@ -1660,54 +1801,6 @@
 		type.sourceStart(),
 		type.sourceEnd());
 }
-public void illegalModifierForAnnotationType(SourceTypeBinding type) {
-	String[] arguments = new String[] {new String(type.sourceName())};
-	this.handle(
-		IProblem.IllegalModifierForAnnotationType,
-		arguments,
-		arguments,
-		type.sourceStart(),
-		type.sourceEnd());
-}
-public void illegalModifierForAnnotationMemberType(SourceTypeBinding type) {
-	String[] arguments = new String[] {new String(type.sourceName())};
-	this.handle(
-		IProblem.IllegalModifierForAnnotationMemberType,
-		arguments,
-		arguments,
-		type.sourceStart(),
-		type.sourceEnd());
-}
-public void illegalModifierForAnnotationField(FieldDeclaration fieldDecl) {
-	String name = new String(fieldDecl.name);
-	this.handle(
-		IProblem.IllegalModifierForAnnotationField,
-		new String[] {
-			new String(fieldDecl.binding.declaringClass.readableName()),
-			name,
-		},		
-		new String[] {
-			new String(fieldDecl.binding.declaringClass.shortReadableName()),
-			name,
-		},		
-		fieldDecl.sourceStart,
-		fieldDecl.sourceEnd);
-}
-
-public void illegalModifierForAnnotationMember(AbstractMethodDeclaration methodDecl) {
-	this.handle(
-		IProblem.IllegalModifierForAnnotationMethod,
-		new String[] {
-			new String(methodDecl.binding.declaringClass.readableName()),
-			new String(methodDecl.selector),
-		},		
-		new String[] {
-			new String(methodDecl.binding.declaringClass.shortReadableName()),
-			new String(methodDecl.selector),
-		},		
-		methodDecl.sourceStart,
-		methodDecl.sourceEnd);
-}
 public void illegalModifierForMethod(AbstractMethodDeclaration methodDecl) {
 	this.handle(
 		IProblem.IllegalModifierForMethod,
@@ -1743,6 +1836,14 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
+public void illegalQualifiedParameterizedTypeAllocation(TypeReference qualifiedTypeReference, TypeBinding allocatedType) {
+	this.handle(
+		IProblem.IllegalQualifiedParameterizedTypeAllocation,
+		new String[] { new String(allocatedType.readableName()), new String(allocatedType.enclosingType().readableName()), },
+		new String[] { new String(allocatedType.shortReadableName()), new String(allocatedType.enclosingType().shortReadableName()), },
+		qualifiedTypeReference.sourceStart,
+		qualifiedTypeReference.sourceEnd);	
+}
 public void illegalStaticModifierForMemberType(SourceTypeBinding type) {
 	String[] arguments = new String[] {new String(type.sourceName())};
 	this.handle(
@@ -1935,14 +2036,6 @@
 		currentMethod.sourceStart(),
 		currentMethod.sourceEnd());
 }
-public void disallowedTargetForAnnotation(Annotation annotation) {
-	this.handle(
-		IProblem.DisallowedTargetForAnnotation,
-		new String[] {new String(annotation.resolvedType.readableName())},
-		new String[] {new String(annotation.resolvedType.shortReadableName())},
-		annotation.sourceStart,
-		annotation.sourceEnd);
-}
 public void incorrectArityForParameterizedType(ASTNode location, TypeBinding type, TypeBinding[] argumentTypes) {
     if (location == null) {
 		this.handle(
@@ -2000,26 +2093,6 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
-public void inheritedMethodsHaveNameClash(SourceTypeBinding type, MethodBinding oneMethod, MethodBinding twoMethod) {
-	this.handle(
-		IProblem.MethodNameClash,
-		new String[] {
-			new String(oneMethod.selector),
-			typesAsString(oneMethod.original().isVarargs(), oneMethod.original().parameters, false),
-			new String(oneMethod.declaringClass.readableName()),
-			typesAsString(twoMethod.original().isVarargs(), twoMethod.original().parameters, false),
-			new String(twoMethod.declaringClass.readableName()),
-		 }, 
-		new String[] {
-			new String(oneMethod.selector),
-			typesAsString(oneMethod.original().isVarargs(), oneMethod.original().parameters, true),
-			new String(oneMethod.declaringClass.shortReadableName()),
-			typesAsString(twoMethod.original().isVarargs(), twoMethod.original().parameters, true),
-			new String(twoMethod.declaringClass.shortReadableName()),
-		 }, 
-		 type.sourceStart(),
-		 type.sourceEnd());
-}	
 public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod, MethodBinding[] abstractMethods) {
 	StringBuffer concreteSignature = new StringBuffer();
 	concreteSignature
@@ -2070,6 +2143,26 @@
 		type.sourceStart(),
 		type.sourceEnd());
 }
+public void inheritedMethodsHaveNameClash(SourceTypeBinding type, MethodBinding oneMethod, MethodBinding twoMethod) {
+	this.handle(
+		IProblem.MethodNameClash,
+		new String[] {
+			new String(oneMethod.selector),
+			typesAsString(oneMethod.original().isVarargs(), oneMethod.original().parameters, false),
+			new String(oneMethod.declaringClass.readableName()),
+			typesAsString(twoMethod.original().isVarargs(), twoMethod.original().parameters, false),
+			new String(twoMethod.declaringClass.readableName()),
+		 }, 
+		new String[] {
+			new String(oneMethod.selector),
+			typesAsString(oneMethod.original().isVarargs(), oneMethod.original().parameters, true),
+			new String(oneMethod.declaringClass.shortReadableName()),
+			typesAsString(twoMethod.original().isVarargs(), twoMethod.original().parameters, true),
+			new String(twoMethod.declaringClass.shortReadableName()),
+		 }, 
+		 type.sourceStart(),
+		 type.sourceEnd());
+}	
 public void initializerMustCompleteNormally(FieldDeclaration fieldDecl) {
 	this.handle(
 		IProblem.InitializerMustCompleteNormally,
@@ -2816,11 +2909,9 @@
 		if (ref.indexOfFirstFieldBinding >= 1)
 			end = (int) ref.sourcePositions[ref.indexOfFirstFieldBinding - 1];
 	} else if (location instanceof ArrayQualifiedTypeReference) {
-		if (!(location instanceof ParameterizedQualifiedTypeReference)) {
-			ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) location;
-			long[] positions = arrayQualifiedTypeReference.sourcePositions;
-			end = (int) positions[positions.length - 1];
-		}
+		ArrayQualifiedTypeReference arrayQualifiedTypeReference = (ArrayQualifiedTypeReference) location;
+		long[] positions = arrayQualifiedTypeReference.sourcePositions;
+		end = (int) positions[positions.length - 1];
 	} else if (location instanceof QualifiedTypeReference) {
 		QualifiedTypeReference ref = (QualifiedTypeReference) location;
 		if (type instanceof ReferenceBinding) {
@@ -2834,10 +2925,8 @@
 			end = (int) ref.sourcePositions[name.length - 1];
 		}
 	} else if (location instanceof ArrayTypeReference) {
-		if (!(location instanceof ParameterizedSingleTypeReference)) {
-			ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location;
-			end = arrayTypeReference.originalSourceEnd;
-		}
+		ArrayTypeReference arrayTypeReference = (ArrayTypeReference) location;
+		end = arrayTypeReference.originalSourceEnd;
 	}
 	this.handle(
 		id,
@@ -3127,7 +3216,18 @@
 public void javadocInvalidConstructor(Statement statement, MethodBinding targetConstructor, int modifiers) {
 
 	if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) return;
+	int sourceStart = statement.sourceStart;
+	int sourceEnd = statement.sourceEnd;
+	if (statement instanceof AllocationExpression) {
+		AllocationExpression allocation = (AllocationExpression)statement;
+		if (allocation.enumConstant != null) {
+			sourceStart = allocation.enumConstant.sourceStart;
+			sourceEnd = allocation.enumConstant.sourceEnd;
+		}
+	}
 	int id = IProblem.JavadocUndefinedConstructor; //default...
+	ProblemMethodBinding problemConstructor = null;
+	MethodBinding shownConstructor = null;
 	switch (targetConstructor.problemId()) {
 		case NotFound :
 			id = IProblem.JavadocUndefinedConstructor;
@@ -3138,6 +3238,109 @@
 		case Ambiguous :
 			id = IProblem.JavadocAmbiguousConstructor;
 			break;
+		case ParameterBoundMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			ParameterizedGenericMethodBinding substitutedConstructor = (ParameterizedGenericMethodBinding) problemConstructor.closestMatch;
+			shownConstructor = substitutedConstructor.original();
+			TypeBinding typeArgument = targetConstructor.parameters[0];
+			TypeVariableBinding typeParameter = (TypeVariableBinding) targetConstructor.parameters[1];
+			this.handle(
+				IProblem.JavadocGenericConstructorTypeArgumentMismatch,
+				new String[] { 
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false), 
+				        new String(shownConstructor.declaringClass.readableName()), 
+				        typesAsString(substitutedConstructor.isVarargs(), substitutedConstructor.parameters, false), 
+				        new String(typeArgument.readableName()), 
+				        new String(typeParameter.sourceName), 
+				        parameterBoundAsString(typeParameter, false) },
+				new String[] { 
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true), 
+				        new String(shownConstructor.declaringClass.shortReadableName()), 
+				        typesAsString(substitutedConstructor.isVarargs(), substitutedConstructor.parameters, true), 
+				        new String(typeArgument.shortReadableName()), 
+				        new String(typeParameter.sourceName), 
+				        parameterBoundAsString(typeParameter, true) },
+				sourceStart,
+				sourceEnd);		    
+			return;		    
+			
+		case TypeParameterArityMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			if (shownConstructor.typeVariables == TypeConstants.NoTypeVariables) {
+				this.handle(
+					IProblem.JavadocNonGenericConstructor,
+					new String[] { 
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false), 
+					        new String(shownConstructor.declaringClass.readableName()), 
+					        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, false) },
+					new String[] { 
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true), 
+					        new String(shownConstructor.declaringClass.shortReadableName()), 
+					        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, true) },
+					sourceStart,
+					sourceEnd);		    
+			} else {
+				this.handle(
+					IProblem.JavadocIncorrectArityForParameterizedConstructor  ,
+					new String[] { 
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false), 
+					        new String(shownConstructor.declaringClass.readableName()), 
+							typesAsString(false, shownConstructor.typeVariables, false),
+					        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, false) },
+					new String[] { 
+					        new String(shownConstructor.declaringClass.sourceName()),
+					        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true), 
+					        new String(shownConstructor.declaringClass.shortReadableName()), 
+							typesAsString(false, shownConstructor.typeVariables, true),
+					        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, true) },
+					sourceStart,
+					sourceEnd);		    
+			}
+			return;
+		case ParameterizedMethodTypeMismatch :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			this.handle(
+				IProblem.JavadocParameterizedConstructorArgumentTypeMismatch,
+				new String[] { 
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false), 
+				        new String(shownConstructor.declaringClass.readableName()), 
+						typesAsString(false, ((ParameterizedGenericMethodBinding)shownConstructor).typeArguments, false),
+				        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, false) },
+				new String[] { 
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true), 
+				        new String(shownConstructor.declaringClass.shortReadableName()), 
+						typesAsString(false, ((ParameterizedGenericMethodBinding)shownConstructor).typeArguments, true),
+				        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, true) },
+				sourceStart,
+				sourceEnd);		    
+			return;
+		case TypeArgumentsForRawGenericMethod :
+			problemConstructor = (ProblemMethodBinding) targetConstructor;
+			shownConstructor = problemConstructor.closestMatch;
+			this.handle(
+				IProblem.JavadocTypeArgumentsForRawGenericConstructor,
+				new String[] { 
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, false), 
+				        new String(shownConstructor.declaringClass.readableName()), 
+				        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, false) },
+				new String[] { 
+				        new String(shownConstructor.declaringClass.sourceName()),
+				        typesAsString(shownConstructor.isVarargs(), shownConstructor.parameters, true), 
+				        new String(shownConstructor.declaringClass.shortReadableName()), 
+				        typesAsString(targetConstructor.isVarargs(), targetConstructor.parameters, true) },
+				sourceStart,
+				sourceEnd);	
+			return;
 		case NoError : // 0
 		default :
 			needImplementation(); // want to fail to see why we were here...
@@ -3193,10 +3396,40 @@
 public void javadocInvalidMethod(MessageSend messageSend, MethodBinding method, int modifiers) {
 	if (!javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) return;
 	// set problem id
+	ProblemMethodBinding problemMethod = null;
+	MethodBinding shownMethod = null;
 	int id = IProblem.JavadocUndefinedMethod; //default...
 	switch (method.problemId()) {
 		case NotFound :
 			id = IProblem.JavadocUndefinedMethod;
+			problemMethod = (ProblemMethodBinding) method;
+			if (problemMethod.closestMatch != null) {
+					String closestParameterTypeNames = typesAsString(problemMethod.closestMatch.isVarargs(), problemMethod.closestMatch.parameters, false);
+					String parameterTypeNames = typesAsString(method.isVarargs(), method.parameters, false);
+					String closestParameterTypeShortNames = typesAsString(problemMethod.closestMatch.isVarargs(), problemMethod.closestMatch.parameters, true);
+					String parameterTypeShortNames = typesAsString(method.isVarargs(), method.parameters, true);
+					if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){
+						closestParameterTypeShortNames = closestParameterTypeNames;
+						parameterTypeShortNames = parameterTypeNames;
+					}
+					this.handle(
+						IProblem.JavadocParameterMismatch,
+						new String[] {
+							new String(problemMethod.closestMatch.declaringClass.readableName()),
+							new String(problemMethod.closestMatch.selector),
+							closestParameterTypeNames,
+							parameterTypeNames 
+						},
+						new String[] {
+							new String(problemMethod.closestMatch.declaringClass.shortReadableName()),
+							new String(problemMethod.closestMatch.selector),
+							closestParameterTypeShortNames,
+							parameterTypeShortNames
+						},
+						(int) (messageSend.nameSourcePosition >>> 32),
+						(int) messageSend.nameSourcePosition);
+					return;
+			}
 			break;
 		case NotVisible :
 			id = IProblem.JavadocNotVisibleMethod;
@@ -3207,41 +3440,113 @@
 		case InheritedNameHidesEnclosingName :
 			id = IProblem.JavadocInheritedMethodHidesEnclosingName;
 			break;
+		case ParameterBoundMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			ParameterizedGenericMethodBinding substitutedMethod = (ParameterizedGenericMethodBinding) problemMethod.closestMatch;
+			shownMethod = substitutedMethod.original();
+			TypeBinding typeArgument = method.parameters[0];
+			TypeVariableBinding typeParameter = (TypeVariableBinding) method.parameters[1];
+			this.handle(
+				IProblem.JavadocGenericMethodTypeArgumentMismatch,
+				new String[] { 
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false), 
+				        new String(shownMethod.declaringClass.readableName()), 
+				        typesAsString(substitutedMethod.isVarargs(), substitutedMethod.parameters, false), 
+				        new String(typeArgument.readableName()), 
+				        new String(typeParameter.sourceName), 
+				        parameterBoundAsString(typeParameter, false) },
+				new String[] { 
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true), 
+				        new String(shownMethod.declaringClass.shortReadableName()), 
+				        typesAsString(substitutedMethod.isVarargs(), substitutedMethod.parameters, true), 
+				        new String(typeArgument.shortReadableName()), 
+				        new String(typeParameter.sourceName), 
+				        parameterBoundAsString(typeParameter, true) },
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);		    
+			return;
+		case TypeParameterArityMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			if (shownMethod.typeVariables == TypeConstants.NoTypeVariables) {
+				this.handle(
+					IProblem.JavadocNonGenericMethod ,
+					new String[] { 
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false), 
+					        new String(shownMethod.declaringClass.readableName()), 
+					        typesAsString(method.isVarargs(), method.parameters, false) },
+					new String[] { 
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true), 
+					        new String(shownMethod.declaringClass.shortReadableName()), 
+					        typesAsString(method.isVarargs(), method.parameters, true) },
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);		    
+			} else {
+				this.handle(
+					IProblem.JavadocIncorrectArityForParameterizedMethod  ,
+					new String[] { 
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false), 
+					        new String(shownMethod.declaringClass.readableName()), 
+							typesAsString(false, shownMethod.typeVariables, false),
+					        typesAsString(method.isVarargs(), method.parameters, false) },
+					new String[] { 
+					        new String(shownMethod.selector),
+					        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true), 
+					        new String(shownMethod.declaringClass.shortReadableName()), 
+							typesAsString(false, shownMethod.typeVariables, true),
+					        typesAsString(method.isVarargs(), method.parameters, true) },
+					(int) (messageSend.nameSourcePosition >>> 32),
+					(int) messageSend.nameSourcePosition);		    
+			}
+			return;
+		case ParameterizedMethodTypeMismatch :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			this.handle(
+				IProblem.JavadocParameterizedMethodArgumentTypeMismatch,
+				new String[] { 
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false), 
+				        new String(shownMethod.declaringClass.readableName()), 
+						typesAsString(false, ((ParameterizedGenericMethodBinding)shownMethod).typeArguments, false),
+				        typesAsString(method.isVarargs(), method.parameters, false) },
+				new String[] { 
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true), 
+				        new String(shownMethod.declaringClass.shortReadableName()), 
+						typesAsString(false, ((ParameterizedGenericMethodBinding)shownMethod).typeArguments, true),
+				        typesAsString(method.isVarargs(), method.parameters, true) },
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);		    
+			return;
+		case TypeArgumentsForRawGenericMethod :
+			problemMethod = (ProblemMethodBinding) method;
+			shownMethod = problemMethod.closestMatch;
+			this.handle(
+				IProblem.JavadocTypeArgumentsForRawGenericMethod ,
+				new String[] { 
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, false), 
+				        new String(shownMethod.declaringClass.readableName()), 
+				        typesAsString(method.isVarargs(), method.parameters, false) },
+				new String[] { 
+				        new String(shownMethod.selector),
+				        typesAsString(shownMethod.isVarargs(), shownMethod.parameters, true), 
+				        new String(shownMethod.declaringClass.shortReadableName()), 
+				        typesAsString(method.isVarargs(), method.parameters, true) },
+				(int) (messageSend.nameSourcePosition >>> 32),
+				(int) messageSend.nameSourcePosition);		       
+			return;
 		case NoError : // 0
 		default :
 			needImplementation(); // want to fail to see why we were here...
 			break;
 	}
-	if (id == IProblem.JavadocUndefinedMethod) {
-		ProblemMethodBinding problemMethod = (ProblemMethodBinding) method;
-		if (problemMethod.closestMatch != null) {
-				String closestParameterTypeNames = typesAsString(problemMethod.closestMatch.isVarargs(), problemMethod.closestMatch.parameters, false);
-				String parameterTypeNames = typesAsString(method.isVarargs(), method.parameters, false);
-				String closestParameterTypeShortNames = typesAsString(problemMethod.closestMatch.isVarargs(), problemMethod.closestMatch.parameters, true);
-				String parameterTypeShortNames = typesAsString(method.isVarargs(), method.parameters, true);
-				if (closestParameterTypeShortNames.equals(parameterTypeShortNames)){
-					closestParameterTypeShortNames = closestParameterTypeNames;
-					parameterTypeShortNames = parameterTypeNames;
-				}
-				this.handle(
-					IProblem.JavadocParameterMismatch,
-					new String[] {
-						new String(problemMethod.closestMatch.declaringClass.readableName()),
-						new String(problemMethod.closestMatch.selector),
-						closestParameterTypeNames,
-						parameterTypeNames 
-					},
-					new String[] {
-						new String(problemMethod.closestMatch.declaringClass.shortReadableName()),
-						new String(problemMethod.closestMatch.selector),
-						closestParameterTypeShortNames,
-						parameterTypeShortNames
-					},
-					(int) (messageSend.nameSourcePosition >>> 32),
-					(int) messageSend.nameSourcePosition);
-				return;
-		}
-	}
 	// report issue
 	this.handle(
 		id,
@@ -3471,21 +3776,30 @@
 			local.sourceEnd);
 	}
 }
+public void methodMustOverride(AbstractMethodDeclaration method) {
+	MethodBinding binding = method.binding;
+	this.handle(
+		IProblem.MethodMustOverride,
+		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true), new String(binding.declaringClass.shortReadableName()),},
+		method.sourceStart,
+		method.sourceEnd);
+}
 public void methodNameClash(MethodBinding currentMethod, MethodBinding inheritedMethod) {
 	this.handle(
 		IProblem.MethodNameClash,
 		new String[] {
 			new String(currentMethod.selector),
-			typesAsString(currentMethod.original().isVarargs(), currentMethod.original().parameters, false),
+			typesAsString(currentMethod.isVarargs(), currentMethod.parameters, false),
 			new String(currentMethod.declaringClass.readableName()),
-			typesAsString(inheritedMethod.original().isVarargs(), inheritedMethod.original().parameters, false),
+			typesAsString(inheritedMethod.isVarargs(), inheritedMethod.parameters, false),
 			new String(inheritedMethod.declaringClass.readableName()),
 		 }, 
 		new String[] {
 			new String(currentMethod.selector),
-			typesAsString(currentMethod.original().isVarargs(), currentMethod.original().parameters, true),
+			typesAsString(currentMethod.isVarargs(), currentMethod.parameters, true),
 			new String(currentMethod.declaringClass.shortReadableName()),
-			typesAsString(inheritedMethod.original().isVarargs(), inheritedMethod.original().parameters, true),
+			typesAsString(inheritedMethod.isVarargs(), inheritedMethod.parameters, true),
 			new String(inheritedMethod.declaringClass.shortReadableName()),
 		 }, 
 		currentMethod.sourceStart(),
@@ -3516,24 +3830,51 @@
 		methodDecl.sourceStart,
 		methodDecl.sourceEnd);
 }
-public void parameterizedMemberTypeMissingArguments(ASTNode location, TypeBinding type) {
-	if (location == null) { // binary case
-	    this.handle(
-			IProblem.MissingArgumentsForParameterizedMemberType,
-			new String[] {new String(type.readableName())},
-			new String[] {new String(type.shortReadableName())},
-			AbortCompilation | Error,
-			0,
-			1);
-	    return;
-	}
-    this.handle(
-		IProblem.MissingArgumentsForParameterizedMemberType,
-		new String[] {new String(type.readableName())},
-		new String[] {new String(type.shortReadableName())},
-		location.sourceStart,
-		location.sourceEnd);
+public void missingEnumConstantCase(SwitchStatement switchStatement, FieldBinding enumConstant) {
+	this.handle(
+		IProblem.MissingEnumConstantCase,
+		new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) },
+		new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) },
+		switchStatement.expression.sourceStart,
+		switchStatement.expression.sourceEnd);
 }
+public void missingOverrideAnnotation(AbstractMethodDeclaration method) {
+	MethodBinding binding = method.binding;
+	this.handle(
+		IProblem.MissingOverrideAnnotation,
+		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true), new String(binding.declaringClass.shortReadableName()),},
+		method.sourceStart,
+		method.sourceEnd);
+}
+public void missingDeprecatedAnnotationForField(FieldDeclaration field) {
+	FieldBinding binding = field.binding;
+	this.handle(
+		IProblem.FieldMissingDeprecatedAnnotation,
+		new String[] {new String(binding.declaringClass.readableName()), new String(binding.name), },
+		new String[] {new String(binding.declaringClass.shortReadableName()), new String(binding.name), },
+		field.sourceStart,
+		field.sourceEnd);
+}
+public void missingDeprecatedAnnotationForMethod(AbstractMethodDeclaration method) {
+	MethodBinding binding = method.binding;
+	this.handle(
+		IProblem.MethodMissingDeprecatedAnnotation,
+		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false), new String(binding.declaringClass.readableName()), },
+		new String[] {new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true), new String(binding.declaringClass.shortReadableName()),},
+		method.sourceStart,
+		method.sourceEnd);
+}
+public void missingDeprecatedAnnotationForType(TypeDeclaration type) {
+	TypeBinding binding = type.binding;
+	this.handle(
+		IProblem.TypeMissingDeprecatedAnnotation,
+		new String[] {new String(binding.readableName()), },
+		new String[] {new String(binding.shortReadableName()),},
+		type.sourceStart,
+		type.sourceEnd);
+}
+
 public void missingReturnType(AbstractMethodDeclaration methodDecl) {
 	this.handle(
 		IProblem.MissingReturnType,
@@ -3604,7 +3945,7 @@
 		methodDecl.sourceEnd);
 }
 public void needImplementation() {
-	this.abortDueToInternalError(Util.bind("abort.missingCode")); //$NON-NLS-1$
+	this.abortDueToInternalError(Messages.abort_missingCode); 
 }
 public void needToEmulateFieldAccess(FieldBinding field, ASTNode location, boolean isReadAccess) {
 	this.handle(
@@ -3620,7 +3961,9 @@
 	MethodBinding method, 
 	ASTNode location) {
 
-	if (method.isConstructor())
+	if (method.isConstructor()) {
+		if (method.declaringClass.isEnum())
+			return; // tolerate emulation for enum constructors, which can only be made private
 		this.handle(
 			IProblem.NeedToEmulateConstructorAccess, 
 			new String[] {
@@ -3633,21 +3976,22 @@
 			 }, 
 			location.sourceStart, 
 			location.sourceEnd); 
-	else
-		this.handle(
-			IProblem.NeedToEmulateMethodAccess, 
-			new String[] {
-				new String(method.declaringClass.readableName()), 
-				new String(method.selector), 
-				typesAsString(method.isVarargs(), method.parameters, false)
-			 }, 
-			new String[] {
-				new String(method.declaringClass.shortReadableName()), 
-				new String(method.selector), 
-				typesAsString(method.isVarargs(), method.parameters, true)
-			 }, 
-			location.sourceStart, 
-			location.sourceEnd); 
+		return;
+	}
+	this.handle(
+		IProblem.NeedToEmulateMethodAccess, 
+		new String[] {
+			new String(method.declaringClass.readableName()), 
+			new String(method.selector), 
+			typesAsString(method.isVarargs(), method.parameters, false)
+		 }, 
+		new String[] {
+			new String(method.declaringClass.shortReadableName()), 
+			new String(method.selector), 
+			typesAsString(method.isVarargs(), method.parameters, true)
+		 }, 
+		location.sourceStart, 
+		location.sourceEnd); 
 }
 public void nestedClassCannotDeclareInterface(TypeDeclaration typeDecl) {
 	String[] arguments = new String[] {new String(typeDecl.name)};
@@ -3742,6 +4086,15 @@
 		location.sourceStart,
 		location.sourceEnd);
 }
+public void nonStaticContextForEnumMemberType(SourceTypeBinding type) {
+	String[] arguments = new String[] {new String(type.sourceName())};
+	this.handle(
+		IProblem.NonStaticContextForEnumMemberType,
+		arguments,
+		arguments,
+		type.sourceStart(),
+		type.sourceEnd());
+}
 public void noSuchEnclosingInstance(TypeBinding targetType, ASTNode location, boolean isConstructorCall) {
 
 	int id;
@@ -3931,6 +4284,24 @@
 	}
 	return nameBuffer.toString();
 }
+public void parameterizedMemberTypeMissingArguments(ASTNode location, TypeBinding type) {
+	if (location == null) { // binary case
+	    this.handle(
+			IProblem.MissingArgumentsForParameterizedMemberType,
+			new String[] {new String(type.readableName())},
+			new String[] {new String(type.shortReadableName())},
+			AbortCompilation | Error,
+			0,
+			1);
+	    return;
+	}
+    this.handle(
+		IProblem.MissingArgumentsForParameterizedMemberType,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		location.sourceStart,
+		location.sourceEnd);
+}
 
 public void parseError(
 	int startPosition, 
@@ -4192,13 +4563,13 @@
 		
 	String[] arguments;
 	if(this.referenceContext instanceof ConstructorDeclaration) {
-		arguments = new String[] {Util.bind("parser.endOfConstructor")}; //$NON-NLS-1$
+		arguments = new String[] {Messages.parser_endOfConstructor}; 
 	} else if(this.referenceContext instanceof MethodDeclaration) {
-		arguments = new String[] {Util.bind("parser.endOfMethod")}; //$NON-NLS-1$
+		arguments = new String[] {Messages.parser_endOfMethod}; 
 	} else if(this.referenceContext instanceof TypeDeclaration) {
-		arguments = new String[] {Util.bind("parser.endOfInitializer")}; //$NON-NLS-1$
+		arguments = new String[] {Messages.parser_endOfInitializer}; 
 	} else {
-		arguments = new String[] {Util.bind("parser.endOfFile")}; //$NON-NLS-1$
+		arguments = new String[] {Messages.parser_endOfFile}; 
 	}
 	this.handle(
 		IProblem.ParsingErrorUnexpectedEOF,
@@ -4301,6 +4672,7 @@
 
 	int flag = IProblem.ParsingErrorNoSuggestion;
 	int startPos = scanner.startPosition;
+	int endPos = scanner.currentPosition - 1;
 
 	//special treatment for recognized errors....
 	if (errorTokenName.equals(Scanner.END_OF_SOURCE))
@@ -4324,6 +4696,18 @@
 			checkPos --;
 		}
 		startPos = checkPos;
+	} else if (errorTokenName.equals(Scanner.INVALID_LOW_SURROGATE)) {
+		flag = IProblem.InvalidLowSurrogate;
+	} else if (errorTokenName.equals(Scanner.INVALID_HIGH_SURROGATE)) {
+		flag = IProblem.InvalidHighSurrogate;
+		// better locate the error message
+		char[] source = scanner.source;
+		int checkPos = scanner.startPosition + 1;
+		while (checkPos <= endPos){
+			if (source[checkPos] == '\\') break;
+			checkPos ++;
+		}
+		endPos = checkPos - 1;
 	} else if (errorTokenName.equals(Scanner.INVALID_FLOAT))
 		flag = IProblem.InvalidFloat;
 	else if (errorTokenName.equals(Scanner.UNTERMINATED_STRING))
@@ -4344,7 +4728,7 @@
 		arguments,
 		// this is the current -invalid- token position
 		startPos, 
-		scanner.currentPosition - 1,
+		endPos,
 		parser.compilationUnit.compilationResult);
 }
 public void shouldReturn(TypeBinding returnType, ASTNode location) {
@@ -4570,6 +4954,15 @@
 		typeDecl.sourceEnd,
 		compUnitDecl.compilationResult);
 }
+public void typeHiding(TypeParameter typeParam, Binding hidden) {
+	TypeBinding hiddenType = (TypeBinding) hidden;
+	this.handle(
+		IProblem.TypeParameterHidingType,
+		new String[] { new String(typeParam.name) , new String(hiddenType.readableName())  },
+		new String[] { new String(typeParam.name) , new String(hiddenType.shortReadableName()) },
+		typeParam.sourceStart,
+		typeParam.sourceEnd);
+	}
 public void typeMismatchError(TypeBinding actualType, TypeBinding expectedType, ASTNode location) {
 	this.handle(
 		IProblem.TypeMismatch,
@@ -4720,15 +5113,6 @@
 		castExpression.sourceStart,
 		castExpression.sourceEnd);
 }
-public void unnecessaryCastForArgument(CastExpression castExpression, TypeBinding parameterType) {
-	TypeBinding castedExpressionType = castExpression.expression.resolvedType;
-	this.handle(
-		IProblem.UnnecessaryArgumentCast,
-		new String[]{ new String(castedExpressionType.readableName()), new String(castExpression.resolvedType.readableName()), new String(parameterType.readableName())},
-		new String[]{ new String(castedExpressionType.shortReadableName()), new String(castExpression.resolvedType.shortReadableName()), new String(parameterType.shortReadableName())},
-		castExpression.sourceStart,
-		castExpression.sourceEnd);
-}
 public void unnecessaryElse(ASTNode location) {
 	this.handle(
 		IProblem.UnnecessaryElse,
@@ -4830,14 +5214,6 @@
 		castExpression.sourceStart,
 		castExpression.sourceEnd);
 }
-public void unsafeRawConversion(Expression expression, TypeBinding expressionType, TypeBinding expectedType) {
-	this.handle(
-		IProblem.UnsafeRawConversion,
-		new String[] { new String(expressionType.readableName()), new String(expectedType.readableName()), new String(expectedType.erasure().readableName()) },
-		new String[] { new String(expressionType.shortReadableName()), new String(expectedType.shortReadableName()), new String(expectedType.erasure().shortReadableName()) },
-		expression.sourceStart,
-		expression.sourceEnd);    
-}
 public void unsafeRawFieldAssignment(FieldBinding rawField, TypeBinding expressionType, ASTNode location) {
 	this.handle(
 		IProblem.UnsafeRawFieldAssignment,
@@ -4848,6 +5224,43 @@
 		location.sourceStart,
 		location.sourceEnd);    
 }
+public void unsafeRawGenericMethodInvocation(ASTNode location, MethodBinding rawMethod) {
+    if (rawMethod.isConstructor()) {
+		this.handle(
+			IProblem.UnsafeRawGenericConstructorInvocation, // The generic constructor {0}({1}) of type {2} is applied to non-parameterized type arguments ({3})
+			new String[] {
+				new String(rawMethod.declaringClass.sourceName()),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.original().parameters, false),
+				new String(rawMethod.declaringClass.readableName()),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.parameters, false),
+			 }, 
+			new String[] {
+				new String(rawMethod.declaringClass.sourceName()),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.original().parameters, true),
+				new String(rawMethod.declaringClass.shortReadableName()),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.parameters, true),
+			 }, 
+			location.sourceStart,
+			location.sourceEnd);    
+    } else {
+		this.handle(
+			IProblem.UnsafeRawGenericMethodInvocation,
+			new String[] {
+				new String(rawMethod.selector),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.original().parameters, false),
+				new String(rawMethod.declaringClass.readableName()),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.parameters, false),
+			 }, 
+			new String[] {
+				new String(rawMethod.selector),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.original().parameters, true),
+				new String(rawMethod.declaringClass.shortReadableName()),
+				typesAsString(rawMethod.original().isVarargs(), rawMethod.parameters, true),
+			 }, 
+			location.sourceStart,
+			location.sourceEnd);    
+    }
+}
 public void unsafeRawInvocation(ASTNode location, MethodBinding rawMethod) {
     if (rawMethod.isConstructor()) {
 		this.handle(
@@ -4883,8 +5296,14 @@
 			location.sourceEnd);    
     }
 }
-public void unsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod, ASTNode location) {
-	
+public void unsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod, SourceTypeBinding type) {
+	int start = type.sourceStart();
+	int end = type.sourceEnd();
+	if (currentMethod.declaringClass == type) {
+		ASTNode location = ((MethodDeclaration) currentMethod.sourceMethod()).returnType;
+		start = location.sourceStart();
+		end = location.sourceEnd();
+	}
 	this.handle(
 			IProblem.UnsafeReturnTypeOverride,
 			new String[] {
@@ -4893,6 +5312,7 @@
 				typesAsString(currentMethod.original().isVarargs(), currentMethod.original().parameters, false),
 				new String(currentMethod.declaringClass.readableName()),
 				new String(inheritedMethod.returnType.readableName()),
+				new String(inheritedMethod.declaringClass.readableName()),
 				//new String(inheritedMethod.returnType.erasure().readableName()),
 			 }, 
 			new String[] {
@@ -4901,10 +5321,19 @@
 				typesAsString(currentMethod.original().isVarargs(), currentMethod.original().parameters, true),
 				new String(currentMethod.declaringClass.shortReadableName()),
 				new String(inheritedMethod.returnType.shortReadableName()),
+				new String(inheritedMethod.declaringClass.shortReadableName()),
 				//new String(inheritedMethod.returnType.erasure().shortReadableName()),
 			 }, 
-			location.sourceStart,
-			location.sourceEnd);
+			start,
+			end);
+}
+public void unsafeTypeConversion(Expression expression, TypeBinding expressionType, TypeBinding expectedType) {
+	this.handle(
+		IProblem.UnsafeTypeConversion,
+		new String[] { new String(expressionType.readableName()), new String(expectedType.readableName()), new String(expectedType.erasure().readableName()) },
+		new String[] { new String(expressionType.shortReadableName()), new String(expectedType.shortReadableName()), new String(expectedType.erasure().shortReadableName()) },
+		expression.sourceStart,
+		expression.sourceEnd);    
 }
 public void unusedArgument(LocalDeclaration localDecl) {
 
@@ -5125,6 +5554,26 @@
 			location.sourceEnd());
 	}
 }
+public void varargsConflict(MethodBinding method1, MethodBinding method2, SourceTypeBinding type) {
+	this.handle(
+		IProblem.VarargsConflict,
+		new String[] { 
+		        new String(method1.selector),
+		        typesAsString(method1.isVarargs(), method1.parameters, false),
+		        new String(method1.declaringClass.readableName()),
+		        typesAsString(method2.isVarargs(), method2.parameters, false),
+		        new String(method2.declaringClass.readableName())
+		},
+		new String[] { 
+		        new String(method1.selector),
+		        typesAsString(method1.isVarargs(), method1.parameters, true),
+		        new String(method1.declaringClass.shortReadableName()),
+		        typesAsString(method2.isVarargs(), method2.parameters, true),
+		        new String(method2.declaringClass.shortReadableName())
+		},
+		method1.declaringClass == type ? method1.sourceStart() : type.sourceStart(),
+		method1.declaringClass == type ? method1.sourceEnd() : type.sourceEnd());
+}
 public void variableTypeCannotBeVoid(AbstractVariableDeclaration varDecl) {
 	String[] arguments = new String[] {new String(varDecl.name)};
 	this.handle(
@@ -5169,7 +5618,7 @@
 	TypeBinding offendingParameter = null;
 	for (int i = 0, length = method.parameters.length; i < length; i++) {
 		TypeBinding parameter = method.parameters[i];
-		if (parameter.isWildcard() && (((WildcardBinding) parameter).kind != Wildcard.SUPER)) {
+		if (parameter.isWildcard() && (((WildcardBinding) parameter).boundKind != Wildcard.SUPER)) {
 			offendingParameter = parameter;
 			offendingArgument = arguments[i];
 			break;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java
index d2cf193..5f5b967 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java
index acceeda..df2d5c4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index f2117e2..70fc600 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -1,10 +1,10 @@
 ###############################################################################
-# Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
@@ -32,6 +32,9 @@
 27 = Cannot use an expression of the type {0} as a valid enclosing instance
 28 = No enclosing instance of type {0} is available due to some intermediate constructor invocation
 29 = An anonymous class cannot subclass the final class {0}
+30 = The member annotation {0} can only be defined inside a top-level class or interface
+31 = The member enum {0} cannot be local
+32 = The member enum {0} must be defined inside a static member type
 
 50 = {0} cannot be resolved
 51 = The local variable {0} may not have been initialized
@@ -104,7 +107,7 @@
 135 = Cannot refer to an instance field {0} while explicitly invoking a constructor
 136 = Cannot refer to an instance method while explicitly invoking a constructor
 137 = Recursive constructor invocation {0}({1})
-138 = Cannot refer to ''this'' nor ''super'' while explicitly invoking a constructor
+138 = Cannot refer to 'this' nor 'super' while explicitly invoking a constructor
 139 = Constructor call must be the first statement in a constructor
 140 = Implicit super constructor {0}({1}) is undefined for default constructor. Must define an explicit constructor
 141 = Implicit super constructor {0}({1}) is not visible for default constructor. Must define an explicit constructor
@@ -201,7 +204,7 @@
 251 = Invalid hex literal number
 252 = Invalid octal literal number
 253 = Invalid character constant
-254 = Invalid escape sequence (valid ones are  \\b  \\t  \\n  \\f  \\r  \\"  \\''  \\\\ )
+254 = Invalid escape sequence (valid ones are  \\b  \\t  \\n  \\f  \\r  \\"  \\'  \\\\ )
 255 = Invalid input
 256 = Invalid unicode
 257 = Invalid float literal number
@@ -210,6 +213,10 @@
 260 = Unexpected end of comment
 261 = Non-externalized string literal; it should be followed by //$NON-NLS-<n>$
 262 = Invalid digit (valid ones are 0..9)
+263 = Invalid low surrogate: must be within 0xDC00 and 0xDFFF
+264 = Invalid high surrogate: must be within 0xD800 and 0xDBFF
+
+280 = Discouraged access: {0}
 
 300 = The interface {0} cannot define an initializer
 301 = Duplicate modifier for the type {0}
@@ -271,7 +278,7 @@
 355 = Duplicate method {0}({2}) in type {1}
 356 = Illegal modifier for parameter {0}; only final is permitted
 357 = Duplicate modifier for the method {1} in type {0}
-358 = Illegal modifier for the method {0}.{1}({2})
+358 = Illegal modifier for the method {0}.{2}({1})
 359 = Illegal modifier for the interface method {0}.{1}({2}); only public & abstract are permitted
 360 = The method {1} in type {0} can only set one of public / protected / private
 361 = The method {1} cannot be declared static; static methods can only be declared in a static or top level type
@@ -300,7 +307,7 @@
 ###[obsolete] 384 = The return type {1} is defined in an inherited type and an enclosing scope
 
 385 = The import {0} conflicts with a type defined in the same file
-386 = The import {0} collides with another imported type
+386 = The import {0} collides with another import statement
 387 = Only a type can be imported. {0} resolves to a package
 388 = The import {0} is never used
 390 = The import {0} cannot be resolved
@@ -344,8 +351,8 @@
 432 = Too many fields for type {0}. Maximum is 65535
 433 = Too many methods for type {0}. Maximum is 65535
 
-440 = ''assert'' should not be used as an identifier, since it is a reserved keyword from source level 1.4 on
-441 = ''enum'' should not be used as an identifier, since it is a reserved keyword from source level 1.5 on
+440 = 'assert' should not be used as an identifier, since it is a reserved keyword from source level 1.4 on
+441 = 'enum' should not be used as an identifier, since it is a reserved keyword from source level 5.0 on
 
 450 = {0} {1}
 
@@ -417,7 +424,7 @@
 529 = The type {0} is not an interface; it cannot be specified as a bounded parameter
 530 = Type safety: The constructor {0}({1}) belongs to the raw type {0}. References to generic type {2} should be parameterized
 531 = Type safety: The method {0}({1}) belongs to the raw type {2}. References to generic type {3} should be parameterized
-532 = Type safety: The expression of type {0} is converted to {1} using a raw conversion. References to generic type {2} should be parameterized
+532 = Type safety: The expression of type {0} needs unchecked conversion to conform to {1}
 533 = Cannot use the type parameter {0} in a catch block
 534 = Cannot use the parameterized type {0} either in catch block or throws clause
 535 = Cannot create a generic array of {0}
@@ -444,27 +451,33 @@
 556 = The type {1} cannot extend or implement {0}. A supertype may not specify any wildcard
 557 = The generic class {0} may not subclass java.lang.Throwable
 558 = Illegal class literal for the type parameter {0}
-559 = Type safety: The return type {0} of the method {1}({2}) of type {3} needs unchecked conversion to conform to the return type {4} of inherited method
+559 = Type safety: The return type {0} for {1}({2}) from the type {3} needs unchecked conversion to conform to {4} from the type {5}
 560 = Name clash: The method {0}({1}) of type {2} has the same erasure as {0}({3}) of type {4} but does not override it
 561 = The member type {0}<{1}> must be qualified with a parameterized type, since it is not static
 562 = The member type {0} must be parameterized, since it is qualified with a parameterized type
 563 = The member type {0} cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type {1}
 564 = Bound conflict: {0} is inherited with conflicting arguments
 565 = Duplicate methods named {0} with the parameters ({2}) and ({3}) are defined by the type {1}
+566 = Cannot allocate the member type {0} using a parameterized compound name; use its simple name and an enclosing instance of type {1}
+567 = Duplicate bound {0}
+568 = The array type {0} cannot be used as a type parameter bound
+569 = Type safety: Unchecked invocation {0}({3}) of the generic constructor {0}({1}) of type {2}
+570 = Type safety: Unchecked invocation {0}({3}) of the generic method {0}({1}) of type {2}
+571 = The type parameter {0} is hiding the type {1}
 
 ### FOREACH
 580 = Type mismatch: cannot convert from element type {0} to {1}
 581 = Can only iterate over an array or an instance of java.lang.Iterable
 
 ### SOURCE LEVEL
-590 = Syntax error, type parameters are only available if source level is 1.5
-591 = Syntax error, static imports are only available if source level is 1.5
-592 = Syntax error, ''for each'' statements are only available if source level is 1.5
-593 = Syntax error, parameterized types are only available if source level is 1.5
-594 = Syntax error, enum declarations are only available if source level is 1.5
-595 = Syntax error, varargs are only available if source level is 1.5
-596 = Syntax error, annotations are only available if source level is 1.5
-597 = Syntax error, annotation declarations are only available if source level is 1.5
+590 = Syntax error, type parameters are only available if source level is 5.0
+591 = Syntax error, static imports are only available if source level is 5.0
+592 = Syntax error, 'for each' statements are only available if source level is 5.0
+593 = Syntax error, parameterized types are only available if source level is 5.0
+594 = Syntax error, enum declarations are only available if source level is 5.0
+595 = Syntax error, varargs are only available if source level is 5.0
+596 = Syntax error, annotations are only available if source level is 5.0
+597 = Syntax error, annotation declarations are only available if source level is 5.0
 
 ### ANNOTATIONS
 600 = Illegal modifier for the annotation attribute {0}.{1}; only public & abstract are permitted
@@ -492,6 +505,12 @@
 622 = The annotation @{0} is disallowed for this location
 623 = The method {0}({1}) of type {2} must override a superclass method
 624 = Annotation type declaration cannot have a constructor
+625 = The value for annotation attribute {0}.{1} must be some @{2} annotation 
+626 = The annotation type {0} should not be used as a superinterface for {1}
+627 = The method {0}({1}) of type {2} should be tagged with @Override since it actually overrides a superclass method
+628 = The deprecated field {0}.{1} should be annotated with @Deprecated
+629 = The deprecated method {0}({1}) of type {2} should be annotated with @Deprecated
+630 = The deprecated type {0} should be annotated with @Deprecated
 
 ### CORRUPTED BINARIES
 700 = The class file {0} contains a signature ''{1}'' ill-formed at position {2}
@@ -506,13 +525,28 @@
 752 = Illegal modifier for the local enum {0}; only abstract is permitted
 753 = Illegal modifier for the member enum {0}; only public, protected, private, static & abstract are permitted
 754 = The enum {1} already defines the method {0}({2}) implicitly
-755 = Cannot qualify the name of the enum constant {0} in a case label
+755 = The enum constant {0}.{1} reference cannot be qualified in a case label
 756 = The type {1} may not subclass {0} explicitly
 757 = Cannot invoke super constructor from enum constructor {0}({1})
 758 = The enum {2} can only define the abstract method {0}({1}) if it also defines enum constants with corresponding implementations
+759 = The field {0}.{1} cannot be referenced from an enum case label; only enum constants can be used in enum switch
+760 = Illegal modifier for the enum constructor; only private is permitted.
+761 = The enum constant {0}.{1} has no corresponding case label
 
 ### VARARGS
 800 = Extended dimensions are illegal for a variable argument
 801 = Varargs argument {0} should be cast to {1} when passed to the method {2}({3}) from type {4}
 802 = Varargs argument {0} should be cast to {1} when passed to the constructor {2}({3})
+803 = Varargs methods should only override other varargs methods unlike {2}.{0}({1}) and {4}.{0}({3})
 
+### GENERIC JAVADOC
+850 = Bound mismatch: The generic method {0}({1}) of type {2} is not applicable for the arguments ({3}) since the type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+851 = The method {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
+852 = Incorrect number of type arguments for generic method <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
+853 = The parameterized method <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
+854 = The method {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
+855 = Bound mismatch: The generic constructor {0}({1}) of type {2} is not applicable for the arguments ({3}) since the type {4} is not a valid substitute for the bounded parameter <{5} extends {6}>
+856 = The constructor {0}({1}) of type {2} is not generic; it cannot be parameterized with arguments <{3}>
+857 = Incorrect number of type arguments for generic constructor <{3}>{0}({1}) of type {2}; it cannot be parameterized with arguments <{4}>
+858 = The parameterized constructor <{3}>{0}({1}) of type {2} is not applicable for the arguments ({4})
+859 = The constructor {0}({1}) of raw type {2} is no longer generic; it cannot be parameterized with arguments <{3}>
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java
index 66adf23..f7ab302 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java
index 6f2c816..09a3f1b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java
index 6ea5078..42e6a6e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java
index 7c42adb..64e5f65 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java
index 7437a6d..3f621fa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java
index 1acef0a..534813c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java
index 18656f7..c715dfa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -54,7 +54,7 @@
 
 	public boolean containsKey(Object key) {
 
-		int index = key.hashCode() % this.valueTable.length;
+		int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length;
 		Object currentKey;
 		while ((currentKey = this.keyTable[index]) != null) {
 			if (currentKey.equals(key))
@@ -66,7 +66,7 @@
 
 	public int get(Object key) {
 
-		int index = key.hashCode() % this.valueTable.length;
+		int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length;
 		Object currentKey;
 		while ((currentKey = this.keyTable[index]) != null) {
 			if (currentKey.equals(key))
@@ -76,9 +76,17 @@
 		return -1;
 	}
 
+	public void keysToArray(Object[] array) {
+		int index = 0;
+		for (int i=0, length=this.keyTable.length; i<length; i++) {
+			if (this.keyTable[i] != null)
+				array[index++] = this.keyTable[i];
+		}
+	}
+
 	public int put(Object key, int value) {
 
-		int index = key.hashCode() % this.valueTable.length;
+		int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length;
 		Object currentKey;
 		while ((currentKey = this.keyTable[index]) != null) {
 			if (currentKey.equals(key))
@@ -96,7 +104,7 @@
 
 	public int removeKey(Object key) {
 
-		int index = key.hashCode() % this.valueTable.length;
+		int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length;
 		Object currentKey;
 		while ((currentKey = this.keyTable[index]) != null) {
 			if (currentKey.equals(key)) {
@@ -127,7 +135,7 @@
 	public int size() {
 		return elementSize;
 	}
-
+	
 	public String toString() {
 		String s = ""; //$NON-NLS-1$
 		Object key;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java
index 3fd642a..9091628 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java
index a64e8ea..68fd2d3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
new file mode 100644
index 0000000..67c23f7
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Messages.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+
+public final class Messages {
+	private static class MessagesProperties extends Properties {
+
+		private static final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
+		private static final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
+		private static final long serialVersionUID = 1L;
+
+		private final Map fields;
+
+		public MessagesProperties(Field[] fieldArray, String bundleName) {
+			super();
+			final int len = fieldArray.length;
+			fields = new HashMap(len * 2);
+			for (int i = 0; i < len; i++) {
+				fields.put(fieldArray[i].getName(), fieldArray[i]);
+			}
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object)
+		 */
+		public synchronized Object put(Object key, Object value) {
+			try {
+				Field field = (Field) fields.get(key);
+				if (field == null) {
+					return null;
+				}
+				//can only set value of public static non-final fields
+				if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED)
+					return null;
+				// Set the value into the field. We should never get an exception here because
+				// we know we have a public static non-final field. If we do get an exception, silently
+				// log it and continue. This means that the field will (most likely) be un-initialized and
+				// will fail later in the code and if so then we will see both the NPE and this error.
+				try {
+					field.set(null, value);
+				} catch (Exception e) {
+					// ignore
+				}
+			} catch (SecurityException e) {
+				// ignore
+			}
+			return null;
+		}
+	}
+
+	
+	private static String[] nlSuffixes;
+	private static final String EXTENSION = ".properties"; //$NON-NLS-1$
+
+	private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.compiler.util.messages";//$NON-NLS-1$
+
+	private Messages() {
+		// Do not instantiate
+	}
+
+	public static String compilation_unresolvedProblem;
+	public static String compilation_unresolvedProblems;
+	public static String compilation_request;
+	public static String compilation_loadBinary;
+	public static String compilation_process;
+	public static String compilation_write;
+	public static String compilation_done;
+	public static String compilation_units;
+	public static String compilation_unit;
+	public static String compilation_internalError;
+	public static String output_isFile;
+	public static String output_isFileNotDirectory;
+	public static String output_dirName;
+	public static String output_notValidAll;
+	public static String output_fileName;
+	public static String output_notValid;
+	public static String problem_noSourceInformation;
+	public static String problem_atLine;
+	public static String abort_invalidAttribute;
+	public static String abort_missingCode;
+	public static String abort_againstSourceModel;
+	public static String accept_cannot;
+	public static String parser_incorrectPath;
+	public static String parser_moveFiles;
+	public static String parser_syntaxRecovery;
+	public static String parser_regularParse;
+	public static String parser_missingFile;
+	public static String parser_corruptedFile;
+	public static String parser_endOfFile;
+	public static String parser_endOfConstructor;
+	public static String parser_endOfMethod;
+	public static String parser_endOfInitializer;
+	public static String ast_missingCode;
+	public static String constant_cannotCastedInto;
+	public static String constant_cannotConvertedTo;
+
+	static {
+		initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+	
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @return the manipulated String
+	 */
+	public static String bind(String message) {
+		return bind(message, null);
+	}
+	
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @param binding the object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding) {
+		return bind(message, new Object[] {binding});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @param binding1 An object to be inserted into the message
+	 * @param binding2 A second object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding1, Object binding2) {
+		return bind(message, new Object[] {binding1, binding2});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @param bindings An array of objects to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object[] bindings) {
+		return MessageFormat.format(message, bindings);
+	}
+	
+	/*
+	 * Build an array of directories to search
+	 */
+	private static String[] buildVariants(String root) {
+		if (nlSuffixes == null) {
+			//build list of suffixes for loading resource bundles
+			String nl = Locale.getDefault().toString();
+			ArrayList result = new ArrayList(4);
+			int lastSeparator;
+			while (true) {
+				result.add('_' + nl + EXTENSION);
+				lastSeparator = nl.lastIndexOf('_');
+				if (lastSeparator == -1)
+					break;
+				nl = nl.substring(0, lastSeparator);
+			}
+			//add the empty suffix last (most general)
+			result.add(EXTENSION);
+			nlSuffixes = (String[]) result.toArray(new String[result.size()]);
+		}
+		root = root.replace('.', '/');
+		String[] variants = new String[nlSuffixes.length];
+		for (int i = 0; i < variants.length; i++)
+			variants[i] = root + nlSuffixes[i];
+		return variants;
+	}
+	public static void initializeMessages(String bundleName, Class clazz) {
+		// load the resource bundle and set the fields
+		final Field[] fields = clazz.getDeclaredFields();
+		load(bundleName, clazz.getClassLoader(), fields);
+
+		// iterate over the fields in the class to make sure that there aren't any empty ones
+		final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
+		final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
+		final int numFields = fields.length;
+		for (int i = 0; i < numFields; i++) {
+			Field field = fields[i];
+			if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED)
+				continue;
+			try {
+				// Set the value into the field if its empty. We should never get an exception here because
+				// we know we have a public static non-final field. If we do get an exception, silently
+				// log it and continue. This means that the field will (most likely) be un-initialized and
+				// will fail later in the code and if so then we will see both the NPE and this error.
+				if (field.get(clazz) == null) {
+					String value = "Missing message: " + field.getName() + " in: " + bundleName; //$NON-NLS-1$ //$NON-NLS-2$
+					field.set(null, value);
+				}
+			} catch (IllegalArgumentException e) {
+				// ignore
+			} catch (IllegalAccessException e) {
+				// ignore
+			}
+		}
+	}
+	/**
+	 * Load the given resource bundle using the specified class loader.
+	 */
+	public static void load(final String bundleName, final ClassLoader loader, final Field[] fields) {
+		final String[] variants = buildVariants(bundleName);
+		// search the dirs in reverse order so the cascading defaults is set correctly
+		for (int i = variants.length; --i >= 0;) {
+			final InputStream input = loader.getResourceAsStream(variants[i]);
+			if (input == null)
+				continue;
+			try {
+				final MessagesProperties properties = new MessagesProperties(fields, bundleName);
+				properties.load(input);
+			} catch (IOException e) {
+				// ignore
+			} finally {
+				if (input != null)
+					try {
+						input.close();
+					} catch (IOException e) {
+						// ignore
+					}
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java
index 50c93b0..4e437e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java
index 978c301..8524d4d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -76,8 +76,8 @@
 
 public Object keyForValue(Object valueToMatch) {
 	if (valueToMatch != null)
-		for (int i = 0, l = valueTable.length; i < l; i++)
-			if (valueToMatch.equals(valueTable[i]))
+		for (int i = 0, l = keyTable.length; i < l; i++)
+			if (keyTable[i] != null && valueToMatch.equals(valueTable[i]))
 				return keyTable[i];
 	return null;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java
index 0c5b80b..ea2e743 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
index 609cffb..652da62 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -40,4 +40,4 @@
 	public final static char[] SUFFIX_JAR = SUFFIX_STRING_JAR.toCharArray();
 	public final static char[] SUFFIX_zip = SUFFIX_STRING_zip.toCharArray(); 
 	public final static char[] SUFFIX_ZIP = SUFFIX_STRING_ZIP.toCharArray();
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
index ef2e5bd..63cb886 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,9 +17,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.Locale;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import org.eclipse.jdt.core.compiler.CharOperation;
@@ -29,115 +26,12 @@
 	public interface Displayable {
 		String displayString(Object o);
 	}
-	static {
-		relocalize();
-	}
 
-	/* Bundle containing messages */
-	protected static ResourceBundle bundle;
-	private final static String bundleName =
-		"org.eclipse.jdt.internal.compiler.util.messages"; //$NON-NLS-1$
 	private static final int DEFAULT_READING_SIZE = 8192;
-	
-	private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
-
 	public static String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
 	public static char[] LINE_SEPARATOR_CHARS = LINE_SEPARATOR.toCharArray();
-	private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
 	
 	/**
-	 * Lookup the message with the given ID in this catalog 
-	 */
-	public static String bind(String id) {
-		return bind(id, (String[]) null);
-	}
-	/**
-	 * Lookup the message with the given ID in this catalog and bind its
-	 * substitution locations with the given string.
-	 */
-	public static String bind(String id, String argument) {
-		return bind(id, new String[] { argument });
-	}
-	/**
-	 * Lookup the message with the given ID in this catalog and bind its
-	 * substitution locations with the given strings.
-	 */
-	public static String bind(String id, String argument1, String argument2) {
-		return bind(id, new String[] { argument1, argument2 });
-	}
-	/**
-	 * Lookup the message with the given ID in this catalog and bind its
-	 * substitution locations with the given string values.
-	 */
-	public static String bind(String id, String[] arguments) {
-		if (id == null)
-			return "No message available"; //$NON-NLS-1$
-		String message = null;
-		try {
-			message = bundle.getString(id);
-		} catch (MissingResourceException e) {
-			// If we got an exception looking for the message, fail gracefully by just returning
-			// the id we were looking for.  In most cases this is semi-informative so is not too bad.
-			return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
-		}
-		return bindMessage(message, arguments);
-	}
-	/**
-	 * Bind some message with given string values.
-	 */
-	public static String bindMessage(String message, String[] arguments) {
-		// for compatibility with MessageFormat which eliminates double quotes in original message
-		char[] messageWithNoDoubleQuotes =
-			CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
-	
-		if (arguments == null) return new String(messageWithNoDoubleQuotes);
-	
-		int length = messageWithNoDoubleQuotes.length;
-		int start = 0;
-		int end = length;
-		StringBuffer output = null;
-		while (true) {
-			if ((end = CharOperation.indexOf('{', messageWithNoDoubleQuotes, start)) > -1) {
-				if (output == null) output = new StringBuffer(length+arguments.length*20);
-				output.append(messageWithNoDoubleQuotes, start, end - start);
-				if ((start = CharOperation.indexOf('}', messageWithNoDoubleQuotes, end + 1)) > -1) {
-					int index = -1;
-					String argId = new String(messageWithNoDoubleQuotes, end + 1, start - end - 1);
-					try {
-						index = Integer.parseInt(argId);
-						if (arguments[index] == null) {
-							output.append('{').append(argId).append('}'); // leave parameter in since no better arg '{0}'
-						} else {
-							output.append(arguments[index]);
-						}						
-					} catch (NumberFormatException nfe) { // could be nested message ID {compiler.name}
-						boolean done = false;
-						String argMessage = null;
-						try {
-							argMessage = bundle.getString(argId);
-							output.append(argMessage);
-							done = true;
-						} catch (MissingResourceException e) {
-							// unable to bind argument, ignore (will leave argument in)
-						}
-						if (!done) output.append(messageWithNoDoubleQuotes, end + 1, start - end);
-					} catch (ArrayIndexOutOfBoundsException e) {
-						output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
-					}
-					start++;
-				} else {
-					output.append(messageWithNoDoubleQuotes, end, length);
-					break;
-				}
-			} else {
-				if (output == null) return new String(messageWithNoDoubleQuotes);
-				output.append(messageWithNoDoubleQuotes, start, length - start);
-				break;
-			}
-		}
-		return output.toString();
-	}
-	/**
 	 * Returns the given bytes as a char array using a given encoding (null means platform default).
 	 */
 	public static char[] bytesToChar(byte[] bytes, String encoding) throws IOException {
@@ -390,6 +284,7 @@
 			}
 		}
 	}
+
 	/**
 	 * Returns true iff str.toLowerCase().endsWith(".jar") || str.toLowerCase().endsWith(".zip")
 	 * implementation is not creating extra strings.
@@ -523,17 +418,6 @@
 		}
 		return true;		
 	}
-	/**
-	 * Creates a NLS catalog for the given locale.
-	 */
-	public static void relocalize() {
-		try {
-			bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
-		} catch(MissingResourceException e) {
-			System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
-			throw e;
-		}
-	}
 
 	/**
 	 * Converts a boolean value into Boolean.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSet.java
index 8d91129..6efa459 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSetOfCharArray.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSetOfCharArray.java
new file mode 100644
index 0000000..6aa60cf
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/WeakHashSetOfCharArray.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.util;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
+/**
+ * A hashset of char[] whose values can be garbage collected.
+ */
+public class WeakHashSetOfCharArray {
+	
+	public class HashableWeakReference extends WeakReference {
+		public int hashCode;
+		public HashableWeakReference(char[] referent, ReferenceQueue queue) {
+			super(referent, queue);
+			this.hashCode = CharOperation.hashCode(referent);
+		}
+		public boolean equals(Object obj) {
+			if (!(obj instanceof HashableWeakReference)) return false;
+			char[] referent = (char[]) get();
+			char[] other = (char[]) ((HashableWeakReference) obj).get();
+			if (referent == null) return other == null;
+			return CharOperation.equals(referent, other);
+		}
+		public int hashCode() {
+			return this.hashCode;
+		}
+		public String toString() {
+			char[] referent = (char[]) get();
+			if (referent == null) return "[hashCode=" + this.hashCode + "] <referent was garbage collected>"; //$NON-NLS-1$  //$NON-NLS-2$
+			return "[hashCode=" + this.hashCode + "] \"" + new String(referent) + '\"'; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+	HashableWeakReference[] values;
+	public int elementSize; // number of elements in the table
+	int threshold;
+	ReferenceQueue referenceQueue = new ReferenceQueue();	
+	
+	public WeakHashSetOfCharArray() {
+		this(5);
+	}
+	
+	public WeakHashSetOfCharArray(int size) {
+		this.elementSize = 0;
+		this.threshold = size; // size represents the expected number of elements
+		int extraRoom = (int) (size * 1.75f);
+		if (this.threshold == extraRoom)
+			extraRoom++;
+		this.values = new HashableWeakReference[extraRoom];
+	}
+	
+	/*
+	 * Adds the given char array to this set.
+	 * If a char array that is equals to the given char array already exists, do nothing.
+	 * Returns the existing char array or the new char array if not found.
+	 */
+	public char[] add(char[] array) {
+		cleanupGarbageCollectedValues();
+		int index = (CharOperation.hashCode(array) & 0x7FFFFFFF) % this.values.length;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			char[] referent;
+			if (CharOperation.equals(array, referent = (char[]) currentValue.get())) {
+				return referent;
+			}
+			index = (index + 1) % this.values.length;
+		}
+		this.values[index] = new HashableWeakReference(array, this.referenceQueue);
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+		
+		return array;
+	}
+		
+	private void addValue(HashableWeakReference value) {
+		char[] array = (char[]) value.get();
+		if (array == null) return;
+		int valuesLength = this.values.length;
+		int index = (value.hashCode & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			if (CharOperation.equals(array, (char[]) currentValue.get())) {
+				return;
+			}
+			index = (index + 1) % valuesLength;
+		}
+		this.values[index] = value;
+
+		// assumes the threshold is never equal to the size of the table
+		if (++this.elementSize > this.threshold)
+			rehash();
+	}
+	
+	private void cleanupGarbageCollectedValues() {
+		HashableWeakReference toBeRemoved;
+		while ((toBeRemoved = (HashableWeakReference) this.referenceQueue.poll()) != null) {
+			int hashCode = toBeRemoved.hashCode;
+			int valuesLength = this.values.length;
+			int index = (hashCode & 0x7FFFFFFF) % valuesLength;
+			HashableWeakReference currentValue;
+			while ((currentValue = this.values[index]) != null) {
+				if (currentValue == toBeRemoved) {
+					// replace the value at index with the last value with the same hash
+					int sameHash = index;
+					int current;
+					while ((currentValue = this.values[current = (sameHash + 1) % valuesLength]) != null && currentValue.hashCode == hashCode)
+						sameHash = current;
+					this.values[index] = this.values[sameHash];
+					this.values[sameHash] = null;
+					this.elementSize--;
+					break;
+				}
+				index = (index + 1) % valuesLength;
+			}
+		}
+	}
+	
+	public boolean contains(char[] array) {
+		return get(array) != null;
+	}
+	
+	/*
+	 * Return the char array that is in this set and that is equals to the given char array.
+	 * Return null if not found.
+	 */
+	public char[] get(char[] array) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length;
+		int index = (CharOperation.hashCode(array) & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			char[] referent;
+			if (CharOperation.equals(array, referent = (char[]) currentValue.get())) {
+				return referent;
+			}
+			index = (index + 1) % valuesLength;
+		}
+		return null;
+	}
+		
+	private void rehash() {
+		WeakHashSetOfCharArray newHashSet = new WeakHashSetOfCharArray(this.elementSize * 2);		// double the number of expected elements
+		newHashSet.referenceQueue = this.referenceQueue;
+		HashableWeakReference currentValue;
+		for (int i = 0, length = this.values.length; i < length; i++)
+			if ((currentValue = this.values[i]) != null)
+				newHashSet.addValue(currentValue);
+
+		this.values = newHashSet.values;
+		this.threshold = newHashSet.threshold;
+		this.elementSize = newHashSet.elementSize;
+	}
+
+	/*
+	 * Removes the char array that is in this set and that is equals to the given char array.
+	 * Return the char array that was in the set, or null if not found.
+	 */
+	public char[] remove(char[] array) {
+		cleanupGarbageCollectedValues();
+		int valuesLength = this.values.length;
+		int index = (CharOperation.hashCode(array) & 0x7FFFFFFF) % valuesLength;
+		HashableWeakReference currentValue;
+		while ((currentValue = this.values[index]) != null) {
+			char[] referent;
+			if (CharOperation.equals(array, referent = (char[]) currentValue.get())) {
+				this.elementSize--;
+				this.values[index] = null;
+				rehash();
+				return referent;
+			}
+			index = (index + 1) % valuesLength;
+		}
+		return null;
+	}
+
+	public int size() {
+		return this.elementSize;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer("{"); //$NON-NLS-1$
+		for (int i = 0, length = this.values.length; i < length; i++) {
+			HashableWeakReference value = this.values[i];
+			if (value != null) {
+				char[] ref = (char[]) value.get();
+				if (ref != null) {
+					buffer.append('\"');
+					buffer.append(ref);
+					buffer.append("\", "); //$NON-NLS-1$
+				}
+			}
+		}
+		buffer.append("}"); //$NON-NLS-1$
+		return buffer.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/messages.properties
index 7a53316..602ec2c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/messages.properties
@@ -1,66 +1,62 @@
 ###############################################################################
 # Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
 ### Eclipse Java Core Compiler messages.
 
 ### compilation
-compilation.unresolvedProblem =  Unresolved compilation problem: \n
-compilation.unresolvedProblems = Unresolved compilation problems: \n
-compilation.request    = [parsing    {2} - #{0}/{1}]
-compilation.loadBinary = [reading    {0}.class]
-compilation.process    = [analyzing  {2} - #{0}/{1}]
-compilation.write      = [writing    {1} - #{0}]
-compilation.done       = [completed  {2} - #{0}/{1}]
-compilation.units      = [{0} units compiled]
-compilation.unit       = [{0} unit compiled]
-compilation.internalError = Internal compiler error
+compilation_unresolvedProblem =  Unresolved compilation problem: \n
+compilation_unresolvedProblems = Unresolved compilation problems: \n
+compilation_request    = [parsing    {2} - #{0}/{1}]
+compilation_loadBinary = [reading    {0}.class]
+compilation_process    = [analyzing  {2} - #{0}/{1}]
+compilation_write      = [writing    {1} - #{0}]
+compilation_done       = [completed  {2} - #{0}/{1}]
+compilation_units      = [{0} units compiled]
+compilation_unit       = [{0} unit compiled]
+compilation_internalError = Internal compiler error
 
 ### output
-output.isFile =  The outDir is a file : {0}
-output.isFileNotDirectory = The outDir is a file not a directory.
-output.dirName =  The output dir name is : {0}
-output.notValidAll =  The outDir is not a valid directory name. All the directories cannot be created.
-output.fileName =  file name : {0}
-output.notValid = The outDir is not a valid directory name. The directory cannot be created.
+output_isFile =  The outDir is a file : {0}
+output_isFileNotDirectory = The outDir is a file not a directory.
+output_dirName =  The output dir name is : {0}
+output_notValidAll =  The outDir is not a valid directory name. All the directories cannot be created.
+output_fileName =  file name : {0}
+output_notValid = The outDir is not a valid directory name. The directory cannot be created.
 
 ### problem
-problem.noSourceInformation = \n!! no source information available !!
-problem.atLine = (at line {0})
+problem_noSourceInformation = \n!! no source information available !!
+problem_atLine = (at line {0})
 
 ### abort
-abort.invalidAttribute = SANITY CHECK: Invalid attribute for local variable {0}
-abort.missingCode = Missing code implementation in the compiler
-abort.againstSourceModel = Cannot compile against source model {0} issued from {1}
+abort_invalidAttribute = SANITY CHECK: Invalid attribute for local variable {0}
+abort_missingCode = Missing code implementation in the compiler
+abort_againstSourceModel = Cannot compile against source model {0} issued from {1}
 
 ### accept
-accept.cannot = Cannot accept the compilation unit: 
+accept_cannot = Cannot accept the compilation unit:
 
 ### parser
-parser.incorrectPath = The path for the javadcl.java file is incorrect
-parser.moveFiles = MOVE FILES IN THE Runtime DIRECTORY OF Parser.class
-parser.syntaxRecovery = SYNTAX RECOVERY
-parser.regularParse = REGULAR PARSE
-parser.missingFile = missing file {0}
-parser.corruptedFile = corrupted file {0}
-parser.endOfFile = end of file
-parser.endOfConstructor = end of constructor
-parser.endOfMethod = end of method
-parser.endOfInitializer = end of initializer
+parser_incorrectPath = The path for the javadcl.java file is incorrect
+parser_moveFiles = MOVE FILES IN THE Runtime DIRECTORY OF Parser.class
+parser_syntaxRecovery = SYNTAX RECOVERY
+parser_regularParse = REGULAR PARSE
+parser_missingFile = missing file {0}
+parser_corruptedFile = corrupted file {0}
+parser_endOfFile = end of file
+parser_endOfConstructor = end of constructor
+parser_endOfMethod = end of method
+parser_endOfInitializer = end of initializer
 
 ### ast
-ast.missingCode = Missing code gen implementation
+ast_missingCode = Missing code gen implementation
 
 ### constant
-constant.cannotCastedInto =  {0} constant cannot be casted into {1}
-constant.cannotConvertedTo = {0} constant cannot be converted to {1}
-
-### miscellaneous
-error.undefinedTypeVariable = Undefined type variable: {0}
-error.missingBound = The class files for {0} and {1} are out of sync
\ No newline at end of file
+constant_cannotCastedInto =  {0} constant cannot be casted into {1}
+constant_cannotConvertedTo = {0} constant cannot be converted to {1}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
index 88afc17..14192f3 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,10 +16,10 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.StringTokenizer;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 
-import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaProject;
@@ -95,11 +95,18 @@
      * up to and including J2SE 1.4.
      *
 	 * @since 3.0
+	 * @deprecated Clients should use the {@link #JLS3} AST API instead.
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Clients should use the JLS3 API.
 	public static final int JLS2 = 2;
 	
 	/**
+	 * Internal synonym for {@link #JLS2}. Use to alleviate
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ static final int JLS2_INTERNAL = JLS2;
+
+	/**
 	 * Constant for indicating the AST API that handles JLS3.
 	 * This API is capable of handling all constructs in the
 	 * Java language as described in the Java Language
@@ -107,15 +114,9 @@
      * JLS3 is a superset of all earlier versions of the
      * Java language, and the JLS3 API can be used to manipulate
      * programs written in all versions of the Java language
-     * up to and including J2SE 1.5.
-     * <p>
-     * <b>NOTE:</b>In Eclipse 3.0, there is no underlying parser support for
-     * JLS3 ASTs. This support is planned for the follow-on release of
-     * Eclipse which includes support for J2SE 1.5. Without a parser to create
-     * JLS3 ASTs, they are not much use. Use JLS2 ASTs instead.
-     * </p>
+     * up to and including J2SE 5 (aka JDK 1.5). 
      *
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int JLS3 = 3;
 	
@@ -206,6 +207,7 @@
 				true /*whitespace*/, 
 				false /*nls*/, 
 				ClassFileConstants.JDK1_3 /*sourceLevel*/, 
+				ClassFileConstants.JDK1_5 /*complianceLevel*/, 
 				null/*taskTag*/, 
 				null/*taskPriorities*/,
 				true/*taskCaseSensitive*/);
@@ -215,8 +217,9 @@
 	 * Creates a new, empty abstract syntax tree using default options.
 	 * 
 	 * @see JavaCore#getDefaultOptions()
+	 * @deprecated Clients should port their code to use the new JLS3 AST API and call
+	 *    {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Clients should port their code to use the new JLS3 API and call {@link #newAST(int)} instead of using this constructor.
 	public AST() {
 		this(JavaCore.getDefaultOptions());
 	}
@@ -232,8 +235,7 @@
 	 * @param compilationUnitDeclaration an internal AST node for a compilation unit declaration
 	 * @param source the string of the Java compilation unit
 	 * @param options compiler options
-	 * @param workingCopyOwner the owner of the working copy that the AST is created from, 
-	 *     or <code>null</code> if none
+	 * @param workingCopy the working copy that the AST is created from
 	 * @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
@@ -245,19 +247,20 @@
 		char[] source,
 		Map options,
 		boolean isResolved,
-		WorkingCopyOwner workingCopyOwner,
+		org.eclipse.jdt.internal.core.CompilationUnit workingCopy,
 		IProgressMonitor monitor) {
 		
 		ASTConverter converter = new ASTConverter(options, isResolved, monitor);
 		AST ast = AST.newAST(level);
 		int savedDefaultNodeFlag = ast.getDefaultNodeFlag();
 		ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
-		BindingResolver resolver = isResolved ? new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopyOwner, new DefaultBindingResolver.BindingTables()) : new BindingResolver();
+		BindingResolver resolver = isResolved ? new DefaultBindingResolver(compilationUnitDeclaration.scope, workingCopy.owner, new DefaultBindingResolver.BindingTables()) : new BindingResolver();
 		ast.setBindingResolver(resolver);
 		converter.setAST(ast);
 	
 		CompilationUnit unit = converter.convert(compilationUnitDeclaration, source);
 		unit.setLineEndTable(compilationUnitDeclaration.compilationResult.lineSeparatorPositions);
+		unit.setJavaElement(workingCopy);
 		ast.setDefaultNodeFlag(savedDefaultNodeFlag);
 		return unit;
 	}
@@ -282,8 +285,9 @@
 	 * @param options the table of options (key type: <code>String</code>;
 	 *    value type: <code>String</code>)
 	 * @see JavaCore#getDefaultOptions()
+	 * @deprecated Clients should port their code to use the new JLS3 AST API and call
+	 *    {@link #newAST(int) AST.newAST(AST.JLS3)} instead of using this constructor.
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Clients should port their code to use the new JLS3 API and call {@link #newAST(int)} instead of using this constructor.
 	public AST(Map options) {
 		this(JLS2);
 		Object sourceLevelOption = options.get(JavaCore.COMPILER_SOURCE);
@@ -293,12 +297,20 @@
 		} else if (JavaCore.VERSION_1_5.equals(sourceLevelOption)) {
 			sourceLevel = ClassFileConstants.JDK1_5;
 		}
+		Object complianceLevelOption = options.get(JavaCore.COMPILER_COMPLIANCE);
+		long complianceLevel = ClassFileConstants.JDK1_3;
+		if (JavaCore.VERSION_1_4.equals(complianceLevelOption)) {
+			complianceLevel = ClassFileConstants.JDK1_4;
+		} else if (JavaCore.VERSION_1_5.equals(complianceLevelOption)) {
+			complianceLevel = ClassFileConstants.JDK1_5;
+		}
 		// override scanner if 1.4 or 1.5 asked for
 		this.scanner = new Scanner(
 			true /*comment*/, 
 			true /*whitespace*/, 
 			false /*nls*/, 
 			sourceLevel /*sourceLevel*/,
+			complianceLevel /*complianceLevel*/,
 			null/*taskTag*/, 
 			null/*taskPriorities*/,
 			true/*taskCaseSensitive*/);
@@ -308,12 +320,16 @@
 	 * Creates a new Java abstract syntax tree
      * (AST) following the specified set of API rules. 
      * <p>
-     * Clients should use this method. It is provided only so that
-     * test suites can create AST instances that employ the JLS2 APIs.
+     * Clients should use this method specifing {@link #JLS3} as the
+     * AST level in all cases, even when dealing with JDK 1.3 or 1.4..
      * </p>
      * 
  	 * @param level the API level; one of the LEVEL constants
-	 * @return new AST instance following the specified set of API rules. 
+	 * @return new AST instance following the specified set of API rules.
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the API level is not one of the LEVEL constants</li>
+	 * </ul>
      * @since 3.0
 	 */
 	public static AST newAST(int level) {
@@ -1055,23 +1071,32 @@
 	 * The following type names are supported:
 	 * <ul>
 	 * <li><code>"boolean"</code></li>
-	 * <li><code>"char"</code></li>
 	 * <li><code>"byte"</code></li>
-	 * <li><code>"short"</code></li>
+	 * <li><code>"char"</code></li>
+	 * <li><code>"double"</code></li>
+	 * <li><code>"float"</code></li>
 	 * <li><code>"int"</code></li>
 	 * <li><code>"long"</code></li>
-	 * <li><code>"float"</code></li>
-	 * <li><code>"double"</code></li>
+	 * <li><code>"short"</code></li>
 	 * <li><code>"void"</code></li>
+	 * <li><code>"java.lang.Boolean"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Byte"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Character"</code> (since 3.1)</li>
 	 * <li><code>"java.lang.Class"</code></li>
 	 * <li><code>"java.lang.Cloneable"</code></li>
+	 * <li><code>"java.lang.Double"</code> (since 3.1)</li>
 	 * <li><code>"java.lang.Error"</code></li>
 	 * <li><code>"java.lang.Exception"</code></li>
+	 * <li><code>"java.lang.Float"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Integer"</code> (since 3.1)</li>
+	 * <li><code>"java.lang.Long"</code> (since 3.1)</li>
 	 * <li><code>"java.lang.Object"</code></li>
 	 * <li><code>"java.lang.RuntimeException"</code></li>
+	 * <li><code>"java.lang.Short"</code> (since 3.1)</li>
 	 * <li><code>"java.lang.String"</code></li>
 	 * <li><code>"java.lang.StringBuffer"</code></li>
 	 * <li><code>"java.lang.Throwable"</code></li>
+	 * <li><code>"java.lang.Void"</code> (since 3.1)</li>
 	 * <li><code>"java.io.Serializable"</code></li>
 	 * </ul>
 	 * </p>
@@ -1083,7 +1108,7 @@
 	 */
 	public ITypeBinding resolveWellKnownType(String name) {
 		if (name == null) {
-			throw new IllegalArgumentException();
+			return null;
 		}
 		return getBindingResolver().resolveWellKnownType(name);
 	}
@@ -1214,7 +1239,7 @@
 		result.setIdentifier(identifier);
 		return result;
 	}
-	
+
 	/**
 	 * Creates and returns a new unparented qualified name node for the given 
 	 * qualifier and simple name child node.
@@ -1255,6 +1280,7 @@
 	 * </ul>
 	 */
 	public Name newName(String[] identifiers) {
+		// update internalSetName(String[] if changed
 		int count = identifiers.length;
 		if (count == 0) {
 			throw new IllegalArgumentException();
@@ -1266,6 +1292,83 @@
 		}
 		return result;
 	}
+	
+	/* (omit javadoc for this method)
+	 * This method is a copy of setName(String[]) that doesn't do any validation.
+	 */
+	Name internalNewName(String[] identifiers) {
+		int count = identifiers.length;
+		if (count == 0) {
+			throw new IllegalArgumentException();
+		}
+		final SimpleName simpleName = new SimpleName(this);
+		simpleName.internalSetIdentifier(identifiers[0]);
+		Name result = simpleName;
+		for (int i = 1; i < count; i++) {
+			SimpleName name = new SimpleName(this);
+			name.internalSetIdentifier(identifiers[i]);
+			result = newQualifiedName(result, name);
+		}
+		return result;
+	}
+
+	/**
+	 * Creates and returns a new unparented name node for the given name.
+	 * The name string must consist of 1 or more name segments separated 
+	 * by single dots '.'. Returns a {@link QualifiedName} if the name has
+	 * dots, and a {@link SimpleName} otherwise. Each of the name
+	 * segments should be legal Java identifiers (this constraint may or may 
+	 * not be enforced), and there must be at least one name segment.
+	 * The string must not contains white space, '&lt;', '&gt;',
+	 * '[', ']', or other any other characters that are not
+	 * part of the Java identifiers or separating '.'s.
+	 * 
+	 * @param qualifiedName string consisting of 1 or more name segments,
+	 * each of which is a legal Java identifier, separated  by single dots '.'
+	 * @return a new unparented name node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the string is empty</li>
+	 * <li>the string begins or ends in a '.'</li>
+	 * <li>the string has adjacent '.'s</li>
+	 * <li>the segments between the '.'s are not valid Java identifiers</li>
+	 * </ul>
+	 * @since 3.1
+	 */
+	public Name newName(String qualifiedName) {
+		StringTokenizer t = new StringTokenizer(qualifiedName, ".", true); //$NON-NLS-1$
+		Name result = null;
+		// balance is # of name tokens - # of period tokens seen so far
+		// initially 0; finally 1; should never drop < 0 or > 1
+		int balance = 0;
+		while(t.hasMoreTokens()) {
+			String s = t.nextToken();
+			if (s.indexOf('.') >= 0) {
+				// this is a delimiter
+				if (s.length() > 1) {
+					// too many dots in a row
+					throw new IllegalArgumentException();
+				}
+				balance--;
+				if (balance < 0) {
+					throw new IllegalArgumentException();
+				}
+			} else {
+				// this is an identifier segment
+				balance++;
+				SimpleName name = newSimpleName(s);
+				if (result == null) {
+					result = name;
+				} else {
+					result = newQualifiedName(result, name);
+				}
+			}
+		}
+		if (balance != 1) {
+			throw new IllegalArgumentException();
+		}
+		return result;
+	}
 
 	//=============================== TYPES ===========================
 	/**
@@ -1325,6 +1428,10 @@
 	 * <li>the node belongs to a different AST</li>
 	 * <li>the node already has a parent</li>
 	 * <li>a cycle in would be created</li>
+	 * <li>the element type is null</li>
+	 * <li>the element type is an array type</li>
+	 * <li>the number of dimensions is lower than 1</li>
+	 * <li>the number of dimensions is greater than 1000</li>
 	 * </ul>
 	 */
 	public ArrayType newArrayType(Type elementType, int dimensions) {
@@ -1372,7 +1479,7 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public ParameterizedType newParameterizedType(Type type) {
 		ParameterizedType result = new ParameterizedType(this);
@@ -1394,7 +1501,7 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public QualifiedType newQualifiedType(Type qualifier, SimpleName name) {
 		QualifiedType result = new QualifiedType(this);
@@ -1408,14 +1515,9 @@
 	 * type bound.
 	 * 
 	 * @return a new unparented wildcard type node
-	 * @exception IllegalArgumentException if:
-	 * <ul>
-	 * <li>the node belongs to a different AST</li>
-	 * <li>the node already has a parent</li>
-	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public WildcardType newWildcardType() {
 		WildcardType result = new WildcardType(this);
@@ -1445,11 +1547,6 @@
 	 * unspecified name.
 	 * 
 	 * @return the new unparented package declaration node
-	 * @exception IllegalArgumentException if:
-	 * <ul>
-	 * <li>the node belongs to a different AST</li>
-	 * <li>the node already has a parent</li>
-	 * </ul>
 	 */
 	public PackageDeclaration newPackageDeclaration() {
 		PackageDeclaration result = new PackageDeclaration(this);
@@ -1462,11 +1559,6 @@
 	 * of a type with an unspecified name.
 	 * 
 	 * @return the new unparented import declaration node
-	 * @exception IllegalArgumentException if:
-	 * <ul>
-	 * <li>the node belongs to a different AST</li>
-	 * <li>the node already has a parent</li>
-	 * </ul>
 	 */
 	public ImportDeclaration newImportDeclaration() {
 		ImportDeclaration result = new ImportDeclaration(this);
@@ -1561,7 +1653,7 @@
 	 * @return a new unparented enum constant declaration node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public EnumConstantDeclaration newEnumConstantDeclaration() {
 		EnumConstantDeclaration result = new EnumConstantDeclaration(this);
@@ -1578,7 +1670,7 @@
 	 * @return a new unparented enum declaration node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public EnumDeclaration newEnumDeclaration() {
 		EnumDeclaration result = new EnumDeclaration(this);
@@ -1592,7 +1684,7 @@
 	 * @return a new unparented type parameter node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public TypeParameter newTypeParameter() {
 		TypeParameter result = new TypeParameter(this);
@@ -1607,7 +1699,7 @@
 	 * @return a new unparented annotation type declaration node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public AnnotationTypeDeclaration newAnnotationTypeDeclaration() {
 		AnnotationTypeDeclaration result = new AnnotationTypeDeclaration(this);
@@ -1623,7 +1715,7 @@
 	 * @return a new unparented annotation type member declaration node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public AnnotationTypeMemberDeclaration newAnnotationTypeMemberDeclaration() {
 		AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(this);
@@ -1639,7 +1731,7 @@
 	 * @exception IllegalArgumentException if the primitive type code is invalid
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public Modifier newModifier(Modifier.ModifierKeyword keyword) {
 		Modifier result = new Modifier(this);
@@ -1824,7 +1916,7 @@
 	/**
 	 * Creates and returns a new method reference node.
 	 * Initially the new node has an unspecified, but legal,
-	 * type, and no parameter name. 
+	 * type, not variable arity, and no parameter name. 
 	 * <p>
 	 * Note that this node type is used only inside doc comments
 	 * ({@link Javadoc}).
@@ -1858,6 +1950,7 @@
 	 * <li>the node belongs to a different AST</li>
 	 * <li>the node already has a parent</li>
 	 * <li>a cycle in would be created</li>
+	 * <li>the variable declaration fragment is null</li>
 	 * </ul>
 	 */
 	public VariableDeclarationStatement
@@ -1919,7 +2012,7 @@
 			newTypeDeclarationStatement(AbstractTypeDeclaration decl) {
 		TypeDeclarationStatement result = new TypeDeclarationStatement(this);
 		if (this.apiLevel == AST.JLS2) {
-			result.setTypeDeclaration((TypeDeclaration) decl);
+			result.internalSetTypeDeclaration((TypeDeclaration) decl);
 		}
 		if (this.apiLevel >= AST.JLS3) {
 			result.setDeclaration(decl);
@@ -2139,7 +2232,7 @@
 	 * @return a new unparented throw statement node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public EnhancedForStatement newEnhancedForStatement() {
 		return new EnhancedForStatement(this);
@@ -2173,6 +2266,7 @@
 	 * @param literal the token for the numeric literal as it would 
 	 *    appear in Java source code
 	 * @return a new unparented number literal node
+	 * @exception IllegalArgumentException if the literal is null
 	 */
 	public NumberLiteral newNumberLiteral(String literal) {
 		if (literal == null) {
@@ -2319,6 +2413,8 @@
 	 * <li>the node belongs to a different AST</li>
 	 * <li>the node already has a parent</li>
 	 * <li>a cycle in would be created</li>
+	 * <li>the given fragment is null</li>
+	 * <li>a cycle in would be created</li>
 	 * </ul>
 	 */
 	public VariableDeclarationExpression
@@ -2352,6 +2448,7 @@
 	 * <li>the node belongs to a different AST</li>
 	 * <li>the node already has a parent</li>
 	 * <li>a cycle in would be created</li>
+	 * <li>the given fragment is null</li>
 	 * </ul>
 	 */
 	public FieldDeclaration newFieldDeclaration(VariableDeclarationFragment fragment) {
@@ -2595,7 +2692,7 @@
 	 * @return a new unparented normal annotation node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public NormalAnnotation newNormalAnnotation() {
 		NormalAnnotation result = new NormalAnnotation(this);
@@ -2609,7 +2706,7 @@
 	 * @return a new unparented marker annotation node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public MarkerAnnotation newMarkerAnnotation() {
 		MarkerAnnotation result = new MarkerAnnotation(this);
@@ -2623,7 +2720,7 @@
 	 * @return a new unparented single member annotation node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public SingleMemberAnnotation newSingleMemberAnnotation() {
 		SingleMemberAnnotation result = new SingleMemberAnnotation(this);
@@ -2637,7 +2734,7 @@
 	 * @return a new unparented member value pair node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public MemberValuePair newMemberValuePair() {
 		MemberValuePair result = new MemberValuePair(this);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index ecd5dfc..254116f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,6 +20,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
@@ -45,6 +46,7 @@
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
 
@@ -353,7 +355,7 @@
 	protected void checkAndAddMultipleFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration[] fields, int index, List bodyDeclarations) {
 		if (fields[index] instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
 			org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) fields[index];
-			Initializer initializer = this.ast.newInitializer();
+			Initializer initializer = new Initializer(this.ast);
 			initializer.setBody(convert(oldInitializer.block));
 			setModifiers(initializer, oldInitializer);
 			initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
@@ -417,11 +419,12 @@
 		if (methodDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) {
 			return convert((org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) methodDeclaration);
 		}
-		MethodDeclaration methodDecl = this.ast.newMethodDeclaration();
+		MethodDeclaration methodDecl = new MethodDeclaration(this.ast);
 		setModifiers(methodDecl, methodDeclaration);
 		boolean isConstructor = methodDeclaration.isConstructor();
 		methodDecl.setConstructor(isConstructor);
-		SimpleName methodName = this.ast.newSimpleName(new String(methodDeclaration.selector));
+		final SimpleName methodName = new SimpleName(this.ast);
+		methodName.internalSetIdentifier(new String(methodDeclaration.selector));
 		int start = methodDeclaration.sourceStart;
 		int end = retrieveIdentifierEndPosition(start, methodDeclaration.sourceEnd);
 		methodName.setSourceRange(start, end - start + 1);
@@ -445,11 +448,12 @@
 			org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration constructorDeclaration = (org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration) methodDeclaration;
 			explicitConstructorCall = constructorDeclaration.constructorCall;
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					// set the return type to VOID
-					PrimitiveType returnType = this.ast.newPrimitiveType(PrimitiveType.VOID);
+					PrimitiveType returnType = new PrimitiveType(this.ast);
+					returnType.setPrimitiveTypeCode(PrimitiveType.VOID);
 					returnType.setSourceRange(methodDeclaration.sourceStart, 0);
-					methodDecl.setReturnType(returnType);
+					methodDecl.internalSetReturnType(returnType);
 					break;
 				case AST.JLS3 :
 					methodDecl.setReturnType2(null);
@@ -483,7 +487,7 @@
 				/*
 				 * start or end can be equal to -1 if we have an interface's method.
 				 */
-				block = this.ast.newBlock();
+				block = new Block(this.ast);
 				block.setSourceRange(start, end - start + 1);
 				methodDecl.setBody(block);
 			}
@@ -525,7 +529,7 @@
 					/*
 					 * start or end can be equal to -1 if we have an interface's method.
 					 */
-					Block block = this.ast.newBlock();
+					Block block = new Block(this.ast);
 					block.setSourceRange(start, end - start + 1);
 					methodDecl.setBody(block);
 				}
@@ -535,7 +539,7 @@
 		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = methodDeclaration.typeParameters();
 		if (typeParameters != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -556,13 +560,13 @@
 	}	
 	
 	public ClassInstanceCreation convert(org.eclipse.jdt.internal.compiler.ast.AllocationExpression expression) {
-		ClassInstanceCreation classInstanceCreation = this.ast.newClassInstanceCreation();
+		ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(classInstanceCreation, expression);
 		}
 		if (expression.typeArguments != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -572,8 +576,8 @@
 			}
 		}
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
-				classInstanceCreation.setName(convert(expression.type));
+			case AST.JLS2_INTERNAL :
+				classInstanceCreation.internalSetName(convert(expression.type));
 				break;
 			case AST.JLS3 :
 				classInstanceCreation.setType(convertType(expression.type));
@@ -591,7 +595,7 @@
 	}
 
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression expression) {
-		InfixExpression infixExpression = this.ast.newInfixExpression();
+		InfixExpression infixExpression = new InfixExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(infixExpression, expression);
 		}
@@ -609,7 +613,8 @@
 		checkCanceled();
 		AnnotationTypeDeclaration typeDecl = this.ast.newAnnotationTypeDeclaration();
 		setModifiers(typeDecl, typeDeclaration);
-		SimpleName typeName = this.ast.newSimpleName(new String(typeDeclaration.name));
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(typeDeclaration.name));
 		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
 		typeDecl.setName(typeName);
 		typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
@@ -626,12 +631,13 @@
 	
 	public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration annotationTypeMemberDeclaration) {
 		checkCanceled();
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			return null;
 		}
-		AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration2 = this.ast.newAnnotationTypeMemberDeclaration();
+		AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration2 = new AnnotationTypeMemberDeclaration(this.ast);
 		setModifiers(annotationTypeMemberDeclaration2, annotationTypeMemberDeclaration);
-		SimpleName methodName = this.ast.newSimpleName(new String(annotationTypeMemberDeclaration.selector));
+		final SimpleName methodName = new SimpleName(this.ast);
+		methodName.internalSetIdentifier(new String(annotationTypeMemberDeclaration.selector));
 		int start = annotationTypeMemberDeclaration.sourceStart;
 		int end = retrieveIdentifierEndPosition(start, annotationTypeMemberDeclaration.sourceEnd);
 		methodName.setSourceRange(start, end - start + 1);
@@ -659,9 +665,10 @@
 	}
 	
 	public SingleVariableDeclaration convert(org.eclipse.jdt.internal.compiler.ast.Argument argument) {
-		SingleVariableDeclaration variableDecl = this.ast.newSingleVariableDeclaration();
+		SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
 		setModifiers(variableDecl, argument);
-		SimpleName name = this.ast.newSimpleName(new String(argument.name));
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(argument.name));
 		int start = argument.sourceStart;
 		int nameEnd = argument.sourceEnd;
 		name.setSourceRange(start, nameEnd - start + 1);
@@ -683,6 +690,9 @@
 		 */
 		if (isVarArgs) {
 			setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions + 1);
+			if (extraDimensions != 0) {
+				variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
+			}
 		} else {
 			setTypeForSingleVariableDeclaration(variableDecl, type, extraDimensions);
 		}
@@ -690,7 +700,7 @@
 		
 		if (isVarArgs) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -717,7 +727,7 @@
 	}
 
 	public ArrayCreation convert(org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression expression) {
-		ArrayCreation arrayCreation = this.ast.newArrayCreation();
+		ArrayCreation arrayCreation = new ArrayCreation(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(arrayCreation, expression);
 		}
@@ -767,7 +777,7 @@
 	}
 
 	public ArrayInitializer convert(org.eclipse.jdt.internal.compiler.ast.ArrayInitializer expression) {
-		ArrayInitializer arrayInitializer = this.ast.newArrayInitializer();
+		ArrayInitializer arrayInitializer = new ArrayInitializer(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(arrayInitializer, expression);
 		}
@@ -787,7 +797,7 @@
 	}
 
 	public ArrayAccess convert(org.eclipse.jdt.internal.compiler.ast.ArrayReference reference) {
-		ArrayAccess arrayAccess = this.ast.newArrayAccess();
+		ArrayAccess arrayAccess = new ArrayAccess(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(arrayAccess, reference);
 		}
@@ -798,13 +808,13 @@
 	}
 
 	public AssertStatement convert(org.eclipse.jdt.internal.compiler.ast.AssertStatement statement) {
-		AssertStatement assertStatement = this.ast.newAssertStatement();
+		AssertStatement assertStatement = new AssertStatement(this.ast);
 		int end = statement.assertExpression.sourceEnd + 1;
 		assertStatement.setExpression(convert(statement.assertExpression));
 		org.eclipse.jdt.internal.compiler.ast.Expression exceptionArgument = statement.exceptionArgument;
 		if (exceptionArgument != null) {
-			assertStatement.setMessage(convert(exceptionArgument));
 			end = exceptionArgument.sourceEnd + 1;
+			assertStatement.setMessage(convert(exceptionArgument));
 		}
 		int start = statement.sourceStart;
 		int sourceEnd = retrieveEndingSemiColonPosition(end, this.compilationUnitSource.length);
@@ -813,7 +823,7 @@
 	}
 	
 	public Assignment convert(org.eclipse.jdt.internal.compiler.ast.Assignment expression) {
-		Assignment assignment = this.ast.newAssignment();
+		Assignment assignment = new Assignment(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(assignment, expression);
 		}
@@ -831,13 +841,14 @@
 	 * Used to convert class body declarations
 	 */
 	public TypeDeclaration convert(org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes) {
-		TypeDeclaration typeDecl = this.ast.newTypeDeclaration();
+		final TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
+		typeDecl.setInterface(false);
 		int nodesLength = nodes.length;
 		for (int i = 0; i < nodesLength; i++) {
 			org.eclipse.jdt.internal.compiler.ast.ASTNode node = nodes[i];
 			if (node instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) {
 				org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer = (org.eclipse.jdt.internal.compiler.ast.Initializer) node;
-				Initializer initializer = this.ast.newInitializer();
+				Initializer initializer = new Initializer(this.ast);
 				initializer.setBody(convert(oldInitializer.block));
 				setModifiers(initializer, oldInitializer);
 				initializer.setSourceRange(oldInitializer.declarationSourceStart, oldInitializer.sourceEnd - oldInitializer.declarationSourceStart + 1);
@@ -877,7 +888,7 @@
 	}
 	
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.BinaryExpression expression) {
-		InfixExpression infixExpression = this.ast.newInfixExpression();
+		InfixExpression infixExpression = new InfixExpression(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(infixExpression, expression);
 		}
@@ -956,7 +967,7 @@
 				 			&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.OperatorSHIFT) != expressionOperatorID)
 							&& ((rightOperand.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) == 0))) {
 				 	List extendedOperands = infixExpression.extendedOperands();
-				 	InfixExpression temp = this.ast.newInfixExpression();
+				 	InfixExpression temp = new InfixExpression(this.ast);
 					if (this.resolveBindings) {
 						this.recordNodes(temp, expression);
 					}
@@ -967,7 +978,7 @@
 					int size = extendedOperands.size();
 				 	for (int i = 0; i < size - 1; i++) {
 				 		Expression expr = temp;
-				 		temp = this.ast.newInfixExpression();
+				 		temp = new InfixExpression(this.ast);
 				 		
 						if (this.resolveBindings) {
 							this.recordNodes(temp, expression);
@@ -1025,7 +1036,7 @@
 	}
 
 	public Block convert(org.eclipse.jdt.internal.compiler.ast.Block statement) {
-		Block block = this.ast.newBlock();
+		Block block = new Block(this.ast);
 		if (statement.sourceEnd > 0) {
 			block.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		}
@@ -1044,10 +1055,11 @@
 	}
 	
 	public BreakStatement convert(org.eclipse.jdt.internal.compiler.ast.BreakStatement statement)  {
-		BreakStatement breakStatement = this.ast.newBreakStatement();
+		BreakStatement breakStatement = new BreakStatement(this.ast);
 		breakStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		if (statement.label != null) {
-			SimpleName name = this.ast.newSimpleName(new String(statement.label));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(statement.label));
 			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
 			breakStatement.setLabel(name);
 		}
@@ -1057,7 +1069,7 @@
 		
 		
 	public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) {
-		SwitchCase switchCase = this.ast.newSwitchCase();
+		SwitchCase switchCase = new SwitchCase(this.ast);
 		org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
 		if (constantExpression == null) {
 			switchCase.setExpression(null);
@@ -1070,7 +1082,7 @@
 	}
 
 	public CastExpression convert(org.eclipse.jdt.internal.compiler.ast.CastExpression expression) {
-		CastExpression castExpression = this.ast.newCastExpression();
+		CastExpression castExpression = new CastExpression(this.ast);
 		castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
 		org.eclipse.jdt.internal.compiler.ast.Expression type = expression.type;
 		trimWhiteSpacesAndComments(type);
@@ -1089,19 +1101,17 @@
 	public CharacterLiteral convert(org.eclipse.jdt.internal.compiler.ast.CharLiteral expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		CharacterLiteral literal = this.ast.newCharacterLiteral();
+		CharacterLiteral literal = new CharacterLiteral(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
-		literal.setEscapedValue(new String(tokens));
+		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
 		literal.setSourceRange(sourceStart, length);
 		removeLeadingAndTrailingCommentsFromLiteral(literal);
 		return literal;
 	}
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess expression) {
-		TypeLiteral typeLiteral = this.ast.newTypeLiteral();
+		TypeLiteral typeLiteral = new TypeLiteral(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(typeLiteral, expression);
 		}
@@ -1113,7 +1123,7 @@
 	public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) {
 		this.compilationUnitSource = source;
 		this.scanner.setSource(unit.compilationResult);
-		CompilationUnit compilationUnit = this.ast.newCompilationUnit();
+		CompilationUnit compilationUnit = new CompilationUnit(this.ast);
 		// handle the package declaration immediately
 		// There is no node corresponding to the package declaration
 		if (this.resolveBindings) {
@@ -1141,7 +1151,11 @@
 		if (types != null) {
 			int typesLength = types.length;
 			for (int i = 0; i < typesLength; i++) {
-				ASTNode type = convert(types[i]);
+				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration declaration = types[i];
+				if (CharOperation.equals(declaration.name, TypeConstants.PACKAGE_INFO_NAME)) {
+					continue;
+				}
+				ASTNode type = convert(declaration);
 				if (type == null) {
 					compilationUnit.setFlags(compilationUnit.getFlags() | ASTNode.MALFORMED);
 				} else {
@@ -1172,7 +1186,7 @@
 	}
 
 	public Assignment convert(org.eclipse.jdt.internal.compiler.ast.CompoundAssignment expression) {
-		Assignment assignment = this.ast.newAssignment();
+		Assignment assignment = new Assignment(this.ast);
 		Expression lhs = convert(expression.lhs);
 		assignment.setLeftHandSide(lhs);
 		int start = lhs.getStartPosition();
@@ -1217,7 +1231,7 @@
 	}
 
 	public ConditionalExpression convert(org.eclipse.jdt.internal.compiler.ast.ConditionalExpression expression) {
-		ConditionalExpression conditionalExpression = this.ast.newConditionalExpression();
+		ConditionalExpression conditionalExpression = new ConditionalExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(conditionalExpression, expression);
 		}
@@ -1229,10 +1243,11 @@
 	}
 
 	public ContinueStatement convert(org.eclipse.jdt.internal.compiler.ast.ContinueStatement statement)  {
-		ContinueStatement continueStatement = this.ast.newContinueStatement();
+		ContinueStatement continueStatement = new ContinueStatement(this.ast);
 		continueStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		if (statement.label != null) {
-			SimpleName name = this.ast.newSimpleName(new String(statement.label));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(statement.label));
 			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
 			continueStatement.setLabel(name);
 		}
@@ -1241,7 +1256,7 @@
 	}
 	
 	public DoStatement convert(org.eclipse.jdt.internal.compiler.ast.DoStatement statement) {
-		DoStatement doStatement = this.ast.newDoStatement();
+		DoStatement doStatement = new DoStatement(this.ast);
 		doStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		doStatement.setExpression(convert(statement.condition));
 		doStatement.setBody(convert(statement.action));
@@ -1252,9 +1267,8 @@
 	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.DoubleLiteral expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
+		NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1264,7 +1278,7 @@
 	}
 	
 	public EmptyStatement convert(org.eclipse.jdt.internal.compiler.ast.EmptyStatement statement) {
-		EmptyStatement emptyStatement = this.ast.newEmptyStatement();
+		EmptyStatement emptyStatement = new EmptyStatement(this.ast);
 		emptyStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		return emptyStatement;
 	}
@@ -1272,8 +1286,9 @@
 	// field is an enum constant
 	public EnumConstantDeclaration convert(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration enumConstant) {
 		checkCanceled();
-		EnumConstantDeclaration enumConstantDeclaration = this.ast.newEnumConstantDeclaration();
-		SimpleName typeName = this.ast.newSimpleName(new String(enumConstant.name));
+		EnumConstantDeclaration enumConstantDeclaration = new EnumConstantDeclaration(this.ast);
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(enumConstant.name));
 		typeName.setSourceRange(enumConstant.sourceStart, enumConstant.sourceEnd - enumConstant.sourceStart + 1);
 		enumConstantDeclaration.setName(typeName);
 		int declarationSourceStart = enumConstant.declarationSourceStart;
@@ -1283,9 +1298,10 @@
 			if (initialization instanceof QualifiedAllocationExpression) {
 				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousType = ((QualifiedAllocationExpression) initialization).anonymousType;
 				if (anonymousType != null) {
-					AnonymousClassDeclaration anonymousClassDeclaration = this.ast.newAnonymousClassDeclaration();
+					AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
 					int start = retrieveStartBlockPosition(anonymousType.sourceEnd, anonymousType.bodyEnd);
 					int end = retrieveRightBrace(anonymousType.bodyEnd, declarationSourceEnd);
+					if (end == -1) end = anonymousType.bodyEnd;
 					anonymousClassDeclaration.setSourceRange(start, end - start + 1);
 					enumConstantDeclaration.setAnonymousClassDeclaration(anonymousClassDeclaration);
 					buildBodyDeclarations(anonymousType, anonymousClassDeclaration);
@@ -1316,7 +1332,7 @@
 	}
 
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.EqualExpression expression) {
-		InfixExpression infixExpression = this.ast.newInfixExpression();
+		InfixExpression infixExpression = new InfixExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(infixExpression, expression);
 		}
@@ -1340,7 +1356,7 @@
 		Statement newStatement;
 		int sourceStart = statement.sourceStart;
 		if (statement.isSuperAccess() || statement.isSuper()) {
-			SuperConstructorInvocation superConstructorInvocation = this.ast.newSuperConstructorInvocation();
+			SuperConstructorInvocation superConstructorInvocation = new SuperConstructorInvocation(this.ast);
 			if (statement.qualification != null) {
 				superConstructorInvocation.setExpression(convert(statement.qualification));
 			}
@@ -1352,9 +1368,11 @@
 				}
 			}
 			if (statement.typeArguments != null) {
-				sourceStart = statement.typeArgumentsSourceStart;
+				if (sourceStart > statement.typeArgumentsSourceStart) {
+					sourceStart = statement.typeArgumentsSourceStart;
+				}
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 :
+					case AST.JLS2_INTERNAL :
 						superConstructorInvocation.setFlags(superConstructorInvocation.getFlags() | ASTNode.MALFORMED);
 						break;
 					case AST.JLS3 :
@@ -1366,7 +1384,7 @@
 			}
 			newStatement = superConstructorInvocation;
 		} else {
-			ConstructorInvocation constructorInvocation = this.ast.newConstructorInvocation();
+			ConstructorInvocation constructorInvocation = new ConstructorInvocation(this.ast);
 			org.eclipse.jdt.internal.compiler.ast.Expression[] arguments = statement.arguments;
 			if (arguments != null) {
 				int length = arguments.length;
@@ -1375,9 +1393,11 @@
 				}
 			}
 			if (statement.typeArguments != null) {
-				sourceStart = statement.typeArgumentsSourceStart;
+				if (sourceStart > statement.typeArgumentsSourceStart) {
+					sourceStart = statement.typeArgumentsSourceStart;
+				}
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 :
+					case AST.JLS2_INTERNAL :
 						constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
 						break;
 					case AST.JLS3 :
@@ -1387,6 +1407,10 @@
 					break;
 				}
 			}
+			if (statement.qualification != null) {
+				// this is an error
+				constructorInvocation.setFlags(constructorInvocation.getFlags() | ASTNode.MALFORMED);
+			}
 			newStatement = constructorInvocation;
 		}
 		newStatement.setSourceRange(sourceStart, statement.sourceEnd - sourceStart + 1);
@@ -1509,7 +1533,7 @@
 
 	public StringLiteral convert(org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral expression) {
 		expression.computeConstant();
-		StringLiteral literal = this.ast.newStringLiteral();
+		StringLiteral literal = new StringLiteral(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1519,7 +1543,8 @@
 	}
 
 	public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.FalseLiteral expression) {
-		BooleanLiteral literal = this.ast.newBooleanLiteral(false);
+		final BooleanLiteral literal =  new BooleanLiteral(this.ast);
+		literal.setBooleanValue(false);
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1529,7 +1554,7 @@
 	
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.FieldReference reference) {
 		if (reference.receiver.isSuper()) {
-			SuperFieldAccess superFieldAccess = this.ast.newSuperFieldAccess();
+			final SuperFieldAccess superFieldAccess = new SuperFieldAccess(this.ast);
 			if (this.resolveBindings) {
 				recordNodes(superFieldAccess, reference);
 			}
@@ -1540,7 +1565,8 @@
 					recordNodes(qualifier, reference.receiver);
 				}
 			}
-			SimpleName simpleName = this.ast.newSimpleName(new String(reference.token)); 
+			final SimpleName simpleName = new SimpleName(this.ast);
+			simpleName.internalSetIdentifier(new String(reference.token));
 			int sourceStart = (int)(reference.nameSourcePosition>>>32);
 			int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
 			simpleName.setSourceRange(sourceStart, length);
@@ -1551,13 +1577,14 @@
 			superFieldAccess.setSourceRange(reference.receiver.sourceStart, reference.sourceEnd - reference.receiver.sourceStart + 1);
 			return superFieldAccess;
 		} else {
-			FieldAccess fieldAccess = this.ast.newFieldAccess();
+			final FieldAccess fieldAccess = new FieldAccess(this.ast);
 			if (this.resolveBindings) {
 				recordNodes(fieldAccess, reference);
 			}
 			Expression receiver = convert(reference.receiver);
 			fieldAccess.setExpression(receiver);
-			SimpleName simpleName = this.ast.newSimpleName(new String(reference.token)); 
+			final SimpleName simpleName = new SimpleName(this.ast);
+			simpleName.internalSetIdentifier(new String(reference.token));
 			int sourceStart = (int)(reference.nameSourcePosition>>>32);
 			int length = (int)(reference.nameSourcePosition & 0xFFFFFFFF) - sourceStart + 1;
 			simpleName.setSourceRange(sourceStart, length);
@@ -1573,9 +1600,8 @@
 	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.FloatLiteral expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
+		NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1586,10 +1612,10 @@
 	
 	public Statement convert(ForeachStatement statement) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
+			case AST.JLS2_INTERNAL :
 				return createFakeEmptyStatement(statement);
 			case AST.JLS3 :
-				EnhancedForStatement enhancedForStatement = this.ast.newEnhancedForStatement();
+				EnhancedForStatement enhancedForStatement = new EnhancedForStatement(this.ast);
 				enhancedForStatement.setParameter(convertToSingleVariableDeclaration(statement.elementVariable));
 				enhancedForStatement.setExpression(convert(statement.collection));
 				enhancedForStatement.setBody(convert(statement.action));
@@ -1603,7 +1629,7 @@
 	}
 	
 	public ForStatement convert(org.eclipse.jdt.internal.compiler.ast.ForStatement statement) {
-		ForStatement forStatement = this.ast.newForStatement();
+		ForStatement forStatement = new ForStatement(this.ast);
 		forStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		org.eclipse.jdt.internal.compiler.ast.Statement[] initializations = statement.initializations;
 		if (initializations != null) {
@@ -1647,7 +1673,7 @@
 	}
 	
 	public IfStatement convert(org.eclipse.jdt.internal.compiler.ast.IfStatement statement) {
-		IfStatement ifStatement = this.ast.newIfStatement();
+		IfStatement ifStatement = new IfStatement(this.ast);
 		ifStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		ifStatement.setExpression(convert(statement.condition));
 		ifStatement.setThenStatement(convert(statement.thenStatement));
@@ -1658,7 +1684,7 @@
 	}
 	
 	public InstanceofExpression convert(org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression expression) {
-		InstanceofExpression instanceOfExpression = this.ast.newInstanceofExpression();
+		InstanceofExpression instanceOfExpression = new InstanceofExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(instanceOfExpression, expression);
 		}
@@ -1673,9 +1699,8 @@
 	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteral expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
+		final NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1687,9 +1712,8 @@
 	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
+		NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1722,11 +1746,12 @@
 	}
 	
 	public LabeledStatement convert(org.eclipse.jdt.internal.compiler.ast.LabeledStatement statement) {
-		LabeledStatement labeledStatement = this.ast.newLabeledStatement();
+		LabeledStatement labeledStatement = new LabeledStatement(this.ast);
 		labeledStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);	
 		org.eclipse.jdt.internal.compiler.ast.Statement body = statement.statement;
 		labeledStatement.setBody(convert(body));
-		SimpleName name = this.ast.newSimpleName(new String(statement.label));
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(statement.label));
 		retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
 		labeledStatement.setLabel(name);
 		return labeledStatement;
@@ -1735,9 +1760,8 @@
 	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteral expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
+		final NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1749,9 +1773,8 @@
 	public NumberLiteral convert(org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue expression) {
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		NumberLiteral literal = this.ast.newNumberLiteral(new String(tokens));
+		final NumberLiteral literal = new NumberLiteral(this.ast);
+		literal.internalSetToken(new String(this.compilationUnitSource, sourceStart, length));
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1766,11 +1789,12 @@
 		int sourceStart = expression.sourceStart;
 		if (expression.isSuperAccess()) {
 			// returns a SuperMethodInvocation
-			SuperMethodInvocation superMethodInvocation = this.ast.newSuperMethodInvocation();
+			final SuperMethodInvocation superMethodInvocation = new SuperMethodInvocation(this.ast);
 			if (this.resolveBindings) {
 				recordNodes(superMethodInvocation, expression);
 			}
-			SimpleName name = this.ast.newSimpleName(new String(expression.selector));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(expression.selector));
 			int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
 			int nameSourceLength = (int)(expression.nameSourcePosition & 0xFFFFFFFF) - nameSourceStart + 1;
 			name.setSourceRange(nameSourceStart, nameSourceLength);
@@ -1804,7 +1828,7 @@
 			final TypeReference[] typeArguments = expression.typeArguments;
 			if (typeArguments != null) {
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 :
+					case AST.JLS2_INTERNAL :
 						superMethodInvocation.setFlags(superMethodInvocation.getFlags() | ASTNode.MALFORMED);
 						break;
 					case AST.JLS3 :
@@ -1817,11 +1841,12 @@
 			expr = superMethodInvocation;
 		} else {
 			// returns a MethodInvocation
-			MethodInvocation methodInvocation = this.ast.newMethodInvocation();
+			final MethodInvocation methodInvocation = new MethodInvocation(this.ast);
 			if (this.resolveBindings) {
 				recordNodes(methodInvocation, expression);
 			}
-			SimpleName name = this.ast.newSimpleName(new String(expression.selector));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(expression.selector));
 			int nameSourceStart =  (int) (expression.nameSourcePosition >>> 32);
 			int nameSourceLength = (int)(expression.nameSourcePosition & 0xFFFFFFFF) - nameSourceStart + 1;
 			name.setSourceRange(nameSourceStart, nameSourceLength);
@@ -1861,7 +1886,7 @@
 			final TypeReference[] typeArguments = expression.typeArguments;
 			if (typeArguments != null) {
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 :
+					case AST.JLS2_INTERNAL :
 						methodInvocation.setFlags(methodInvocation.getFlags() | ASTNode.MALFORMED);
 						break;
 					case AST.JLS3 :
@@ -1879,7 +1904,7 @@
 	}
 
 	public MarkerAnnotation convert(org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation annotation) {
-		MarkerAnnotation markerAnnotation = this.ast.newMarkerAnnotation();
+		final MarkerAnnotation markerAnnotation = new MarkerAnnotation(this.ast);
 		setTypeNameForAnnotation(annotation, markerAnnotation);
 		int start = annotation.sourceStart;
 		int end = annotation.declarationSourceEnd;
@@ -1891,15 +1916,17 @@
 	}
 
 	public MemberValuePair convert(org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair) {
-		MemberValuePair pair = this.ast.newMemberValuePair();
-		SimpleName simpleName = this.ast.newSimpleName(new String(memberValuePair.name));
+		final MemberValuePair pair = new MemberValuePair(this.ast);
+		final SimpleName simpleName = new SimpleName(this.ast);
+		simpleName.internalSetIdentifier(new String(memberValuePair.name));
 		int start = memberValuePair.sourceStart;
 		int end = memberValuePair.sourceEnd;
 		simpleName.setSourceRange(start, end - start + 1);
 		pair.setName(simpleName);
-		pair.setValue(convert(memberValuePair.value));
+		final Expression value = convert(memberValuePair.value);
+		pair.setValue(value);
 		start = memberValuePair.sourceStart;
-		end = memberValuePair.value.sourceEnd;
+		end = value.getStartPosition() + value.getLength() - 1;
 		pair.setSourceRange(start, end - start + 1);
 		if (this.resolveBindings) {
 			recordNodes(simpleName, memberValuePair);
@@ -1917,7 +1944,7 @@
 
 	public InfixExpression convert(StringLiteralConcatenation expression) {
 		expression.computeConstant();
-		InfixExpression infixExpression = this.ast.newInfixExpression();
+		final InfixExpression infixExpression = new InfixExpression(this.ast);
 		infixExpression.setOperator(InfixExpression.Operator.PLUS);
 		org.eclipse.jdt.internal.compiler.ast.Expression[] stringLiterals = expression.literals;
 		infixExpression.setLeftOperand(convert(stringLiterals[0]));
@@ -1933,7 +1960,7 @@
 	}
 	
 	public NormalAnnotation convert(org.eclipse.jdt.internal.compiler.ast.NormalAnnotation annotation) {
-		NormalAnnotation normalAnnotation = this.ast.newNormalAnnotation();
+		final NormalAnnotation normalAnnotation = new NormalAnnotation(this.ast);
 		setTypeNameForAnnotation(annotation, normalAnnotation);
 		org.eclipse.jdt.internal.compiler.ast.MemberValuePair[] memberValuePairs = annotation.memberValuePairs;
 		if (memberValuePairs != null) {
@@ -1950,8 +1977,8 @@
 		return normalAnnotation;
 	}
 
-	public org.eclipse.jdt.core.dom.NullLiteral convert(org.eclipse.jdt.internal.compiler.ast.NullLiteral expression) {
-		org.eclipse.jdt.core.dom.NullLiteral literal = this.ast.newNullLiteral();
+	public NullLiteral convert(org.eclipse.jdt.internal.compiler.ast.NullLiteral expression) {
+		final NullLiteral literal = new NullLiteral(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -1960,7 +1987,7 @@
 	}
 
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression expression) {
-		InfixExpression infixExpression = this.ast.newInfixExpression();
+		final InfixExpression infixExpression = new InfixExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(infixExpression, expression);
 		}
@@ -1974,7 +2001,7 @@
 	}
 
 	public PostfixExpression convert(org.eclipse.jdt.internal.compiler.ast.PostfixExpression expression) {
-		PostfixExpression postfixExpression = this.ast.newPostfixExpression();
+		final PostfixExpression postfixExpression = new PostfixExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(postfixExpression, expression);
 		}
@@ -1992,7 +2019,7 @@
 	}
 
 	public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.PrefixExpression expression) {
-		PrefixExpression prefixExpression = this.ast.newPrefixExpression();
+		final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(prefixExpression, expression);
 		}
@@ -2010,13 +2037,13 @@
 	}
 
 	public Expression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression allocation) {
-		ClassInstanceCreation classInstanceCreation = this.ast.newClassInstanceCreation();
+		final ClassInstanceCreation classInstanceCreation = new ClassInstanceCreation(this.ast);
 		if (allocation.enclosingInstance != null) {
 			classInstanceCreation.setExpression(convert(allocation.enclosingInstance));
 		}
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
-				classInstanceCreation.setName(convert(allocation.type));
+			case AST.JLS2_INTERNAL :
+				classInstanceCreation.internalSetName(convert(allocation.type));
 				break;
 			case AST.JLS3 :
 				classInstanceCreation.setType(convertType(allocation.type));
@@ -2034,7 +2061,7 @@
 		}
 		if (allocation.typeArguments != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					classInstanceCreation.setFlags(classInstanceCreation.getFlags() | ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -2046,7 +2073,7 @@
 		if (allocation.anonymousType != null) {
 			int declarationSourceStart = allocation.sourceStart;
 			classInstanceCreation.setSourceRange(declarationSourceStart, allocation.anonymousType.bodyEnd - declarationSourceStart + 1);
-			AnonymousClassDeclaration anonymousClassDeclaration = this.ast.newAnonymousClassDeclaration();
+			final AnonymousClassDeclaration anonymousClassDeclaration = new AnonymousClassDeclaration(this.ast);
 			int start = retrieveStartBlockPosition(allocation.anonymousType.sourceEnd, allocation.anonymousType.bodyEnd);
 			anonymousClassDeclaration.setSourceRange(start, allocation.anonymousType.bodyEnd - start + 1);
 			classInstanceCreation.setAnonymousClassDeclaration(anonymousClassDeclaration);
@@ -2077,7 +2104,7 @@
 	}
 
 	public ThisExpression convert(org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference reference) {
-		ThisExpression thisExpression = this.ast.newThisExpression();
+		final ThisExpression thisExpression = new ThisExpression(this.ast);
 		thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
 		thisExpression.setQualifier(convert(reference.qualification));
 		if (this.resolveBindings) {
@@ -2104,7 +2131,7 @@
 	}
 	
 	public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
-		ReturnStatement returnStatement = this.ast.newReturnStatement();
+		final ReturnStatement returnStatement = new ReturnStatement(this.ast);
 		returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);	
 		if (statement.expression != null) {
 			returnStatement.setExpression(convert(statement.expression));
@@ -2114,7 +2141,7 @@
 	}
 	
 	public SingleMemberAnnotation convert(org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation annotation) {
-		SingleMemberAnnotation singleMemberAnnotation = this.ast.newSingleMemberAnnotation();
+		final SingleMemberAnnotation singleMemberAnnotation = new SingleMemberAnnotation(this.ast);
 		setTypeNameForAnnotation(annotation, singleMemberAnnotation);
 		singleMemberAnnotation.setValue(convert(annotation.memberValue));
 		int start = annotation.sourceStart;
@@ -2127,7 +2154,8 @@
 	}
 
 	public SimpleName convert(org.eclipse.jdt.internal.compiler.ast.SingleNameReference nameReference) {
-		SimpleName name = this.ast.newSimpleName(new String(nameReference.token));		
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(nameReference.token));
 		if (this.resolveBindings) {
 			recordNodes(name, nameReference);
 		}
@@ -2192,25 +2220,30 @@
 		}
 		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
 			ASTNode result = convert((org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) statement);
+			if (result == null) {
+				return createFakeEmptyStatement(statement);
+			}
 			switch(result.getNodeType()) {
 				case ASTNode.ENUM_DECLARATION:
 					switch(this.ast.apiLevel) {
-						case AST.JLS2 :
+						case AST.JLS2_INTERNAL :
 							return createFakeEmptyStatement(statement);
 						case AST.JLS3 :
-							TypeDeclarationStatement typeDeclarationStatement = this.ast.newTypeDeclarationStatement((EnumDeclaration) result);
-							TypeDeclaration typeDecl = typeDeclarationStatement.getTypeDeclaration();
+							final TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
+							typeDeclarationStatement.setDeclaration((EnumDeclaration) result);
+							AbstractTypeDeclaration typeDecl = typeDeclarationStatement.getDeclaration();
 							typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
 							return typeDeclarationStatement;
 					}
 					break;
 				case ASTNode.ANNOTATION_TYPE_DECLARATION :
 					switch(this.ast.apiLevel) {
-						case AST.JLS2 :
+						case AST.JLS2_INTERNAL :
 							return createFakeEmptyStatement(statement);
 						case AST.JLS3 :
-							TypeDeclarationStatement typeDeclarationStatement = this.ast.newTypeDeclarationStatement((AnnotationTypeDeclaration) result);
-							TypeDeclaration typeDecl = typeDeclarationStatement.getTypeDeclaration();
+							TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
+							typeDeclarationStatement.setDeclaration((AnnotationTypeDeclaration) result);
+							AbstractTypeDeclaration typeDecl = typeDeclarationStatement.getDeclaration();
 							typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());
 							return typeDeclarationStatement;
 					}
@@ -2220,15 +2253,16 @@
 					if (typeDeclaration == null) {
 						return createFakeEmptyStatement(statement);
 					} else {
-						TypeDeclarationStatement typeDeclarationStatement = this.ast.newTypeDeclarationStatement(typeDeclaration);
+						TypeDeclarationStatement typeDeclarationStatement = new TypeDeclarationStatement(this.ast);
+						typeDeclarationStatement.setDeclaration(typeDeclaration);
 						switch(this.ast.apiLevel) {
-							case AST.JLS2 :
-								TypeDeclaration typeDecl = typeDeclarationStatement.getTypeDeclaration();
+							case AST.JLS2_INTERNAL :
+								TypeDeclaration typeDecl = typeDeclarationStatement.internalGetTypeDeclaration();
 								typeDeclarationStatement.setSourceRange(typeDecl.getStartPosition(), typeDecl.getLength());					
 								break;
 							case AST.JLS3 :
 								AbstractTypeDeclaration typeDeclAST3 = typeDeclarationStatement.getDeclaration();
-								typeDeclarationStatement.setSourceRange(typeDeclAST3.getStartPosition(), typeDeclAST3.getLength());					
+								typeDeclarationStatement.setSourceRange(typeDeclAST3.getStartPosition(), typeDeclAST3.getLength());
 								break;
 						}
 						return typeDeclarationStatement;
@@ -2239,8 +2273,9 @@
 			return convert((org.eclipse.jdt.internal.compiler.ast.WhileStatement) statement);
 		}
 		if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression) {
-			Expression expr = convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
-			Statement stmt = this.ast.newExpressionStatement(expr);
+			final Expression expr = convert((org.eclipse.jdt.internal.compiler.ast.Expression) statement);
+			final ExpressionStatement stmt = new ExpressionStatement(this.ast);
+			stmt.setExpression(expr);
 			stmt.setSourceRange(expr.getStartPosition(), expr.getLength());
 			retrieveSemiColonPosition(stmt);
 			return stmt;
@@ -2254,19 +2289,17 @@
 		}
 		int length = expression.sourceEnd - expression.sourceStart + 1;	
 		int sourceStart = expression.sourceStart;
-		char[] tokens = new char[length];
-		System.arraycopy(this.compilationUnitSource, sourceStart, tokens, 0, length);
-		StringLiteral literal = this.ast.newStringLiteral();
+		StringLiteral literal = new StringLiteral(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
-		literal.setEscapedValue(new String(tokens));
+		literal.internalSetEscapedValue(new String(this.compilationUnitSource, sourceStart, length));
 		literal.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
 		return literal;
 	}
 	
 	public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) {
-		SwitchStatement switchStatement = this.ast.newSwitchStatement();
+		SwitchStatement switchStatement = new SwitchStatement(this.ast);
 		switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);	
 		switchStatement.setExpression(convert(statement.expression));
 		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = statement.statements;
@@ -2280,7 +2313,7 @@
 	}
 	
 	public SynchronizedStatement convert(org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement statement) {
-		SynchronizedStatement synchronizedStatement = this.ast.newSynchronizedStatement();
+		SynchronizedStatement synchronizedStatement = new SynchronizedStatement(this.ast);
 		synchronizedStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);	
 		synchronizedStatement.setBody(convert(statement.block));
 		synchronizedStatement.setExpression(convert(statement.expression));
@@ -2296,7 +2329,7 @@
 		} else if (reference instanceof org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) {
 			return convert((org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference) reference);
 		}  else {
-			ThisExpression thisExpression = this.ast.newThisExpression();
+			ThisExpression thisExpression = new ThisExpression(this.ast);
 			thisExpression.setSourceRange(reference.sourceStart, reference.sourceEnd - reference.sourceStart + 1);
 			if (this.resolveBindings) {
 				recordNodes(thisExpression, reference);
@@ -2307,7 +2340,7 @@
 	}
 	
 	public ThrowStatement convert(org.eclipse.jdt.internal.compiler.ast.ThrowStatement statement) {
-		ThrowStatement throwStatement = this.ast.newThrowStatement();
+		final ThrowStatement throwStatement = new ThrowStatement(this.ast);
 		throwStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);	
 		throwStatement.setExpression(convert(statement.exception));
 		retrieveSemiColonPosition(throwStatement);
@@ -2315,7 +2348,8 @@
 	}
 		
 	public BooleanLiteral convert(org.eclipse.jdt.internal.compiler.ast.TrueLiteral expression) {
-		BooleanLiteral literal = this.ast.newBooleanLiteral(true);
+		final BooleanLiteral literal = new BooleanLiteral(this.ast);
+		literal.setBooleanValue(true);
 		if (this.resolveBindings) {
 			this.recordNodes(literal, expression);
 		}
@@ -2324,7 +2358,7 @@
 	}
 	
 	public TryStatement convert(org.eclipse.jdt.internal.compiler.ast.TryStatement statement) {
-		TryStatement tryStatement = this.ast.newTryStatement();
+		final TryStatement tryStatement = new TryStatement(this.ast);
 		tryStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);	
 
 		tryStatement.setBody(convert(statement.tryBlock));
@@ -2334,7 +2368,7 @@
 			org.eclipse.jdt.internal.compiler.ast.Block[] catchBlocks = statement.catchBlocks;
 			int start = statement.tryBlock.sourceEnd;
 			for (int i = 0; i < catchArgumentsLength; i++) {
-				CatchClause catchClause = this.ast.newCatchClause();
+				CatchClause catchClause = new CatchClause(this.ast);
 				int catchClauseSourceStart = retrieveStartingCatchPosition(start, catchArguments[i].sourceStart);
 				catchClause.setSourceRange(catchClauseSourceStart, catchBlocks[i].sourceEnd - catchClauseSourceStart + 1);	
 				catchClause.setBody(convert(catchBlocks[i]));
@@ -2352,13 +2386,13 @@
 	public ASTNode convert(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
 		switch (typeDeclaration.kind()) {
 			case IGenericType.ENUM_DECL :
-				if (this.ast.apiLevel == AST.JLS2) {
+				if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 					return null;
 				} else {
 					return convertToEnumDeclaration(typeDeclaration);
 				}
 			case IGenericType.ANNOTATION_TYPE_DECL :
-				if (this.ast.apiLevel == AST.JLS2) {
+				if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 					return null;
 				} else {
 					return convertToAnnotationDeclaration(typeDeclaration);
@@ -2366,12 +2400,13 @@
 		}
 
 		checkCanceled();
-		TypeDeclaration typeDecl = this.ast.newTypeDeclaration();
+		TypeDeclaration typeDecl = new TypeDeclaration(this.ast);
 		if (typeDeclaration.modifiersSourceStart != -1) {
 			setModifiers(typeDecl, typeDeclaration);
 		}
 		typeDecl.setInterface(typeDeclaration.kind() == IGenericType.INTERFACE_DECL);
-		SimpleName typeName = this.ast.newSimpleName(new String(typeDeclaration.name));
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(typeDeclaration.name));
 		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
 		typeDecl.setName(typeName);
 		typeDecl.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
@@ -2380,8 +2415,8 @@
 		// the type references level.
 		if (typeDeclaration.superclass != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
-					typeDecl.setSuperclass(convert(typeDeclaration.superclass));
+				case AST.JLS2_INTERNAL :
+					typeDecl.internalSetSuperclass(convert(typeDeclaration.superclass));
 					break;
 				case AST.JLS3 :
 					typeDecl.setSuperclassType(convertType(typeDeclaration.superclass));
@@ -2392,9 +2427,9 @@
 		org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
 		if (superInterfaces != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					for (int index = 0, length = superInterfaces.length; index < length; index++) {
-						typeDecl.superInterfaces().add(convert(superInterfaces[index]));
+						typeDecl.internalSuperInterfaces().add(convert(superInterfaces[index]));
 					}
 					break;
 				case AST.JLS3 :
@@ -2406,7 +2441,7 @@
 		org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = typeDeclaration.typeParameters;
 		if (typeParameters != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -2425,8 +2460,9 @@
 	}
 
 	public TypeParameter convert(org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter) {
-		TypeParameter typeParameter2 = this.ast.newTypeParameter();
-		SimpleName simpleName = this.ast.newSimpleName(new String(typeParameter.name));
+		final TypeParameter typeParameter2 = new TypeParameter(this.ast);
+		final SimpleName simpleName = new SimpleName(this.ast);
+		simpleName.internalSetIdentifier(new String(typeParameter.name));
 		int start = typeParameter.sourceStart;
 		int end = typeParameter.sourceEnd;
 		simpleName.setSourceRange(start, end - start + 1);
@@ -2461,24 +2497,24 @@
 	public Name convert(org.eclipse.jdt.internal.compiler.ast.TypeReference typeReference) {
 		char[][] typeName = typeReference.getTypeName();
 		int length = typeName.length;
-		Name name = null;
 		if (length > 1) {
 			// QualifiedName
 			org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference qualifiedTypeReference = (org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference;
-			long[] positions = qualifiedTypeReference.sourcePositions;			
-			name = setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
+			final long[] positions = qualifiedTypeReference.sourcePositions;			
+			return setQualifiedNameNameAndSourceRanges(typeName, positions, typeReference);
 		} else {
-			name = this.ast.newSimpleName(new String(typeName[0]));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(typeName[0]));
 			name.setSourceRange(typeReference.sourceStart, typeReference.sourceEnd - typeReference.sourceStart + 1);
+			if (this.resolveBindings) {
+				recordNodes(name, typeReference);
+			}
+			return name;
 		}
-		if (this.resolveBindings) {
-			recordNodes(name, typeReference);
-		}
-		return name;
 	}
 			
 	public PrefixExpression convert(org.eclipse.jdt.internal.compiler.ast.UnaryExpression expression) {
-		PrefixExpression prefixExpression = this.ast.newPrefixExpression();
+		final PrefixExpression prefixExpression = new PrefixExpression(this.ast);
 		if (this.resolveBindings) {
 			this.recordNodes(prefixExpression, expression);
 		}
@@ -2501,7 +2537,7 @@
 	}
 	
 	public WhileStatement convert(org.eclipse.jdt.internal.compiler.ast.WhileStatement statement) {
-		WhileStatement whileStatement = this.ast.newWhileStatement();
+		final WhileStatement whileStatement = new WhileStatement(this.ast);
 		whileStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
 		whileStatement.setExpression(convert(statement.condition));
 		org.eclipse.jdt.internal.compiler.ast.Statement action = statement.action;
@@ -2510,27 +2546,30 @@
 	}
 	
 	public ImportDeclaration convertImport(org.eclipse.jdt.internal.compiler.ast.ImportReference importReference) {
-		ImportDeclaration importDeclaration = this.ast.newImportDeclaration();
-		boolean onDemand = importReference.onDemand;
-		char[][] tokens = importReference.tokens;
+		final ImportDeclaration importDeclaration = new ImportDeclaration(this.ast);
+		final boolean onDemand = importReference.onDemand;
+		final char[][] tokens = importReference.tokens;
 		int length = importReference.tokens.length;
-		long[] positions = importReference.sourcePositions;
-		Name name = null;
+		final long[] positions = importReference.sourcePositions;
 		if (length > 1) {
-			name = setQualifiedNameNameAndSourceRanges(tokens, positions, importReference);
+			importDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
 		} else {
-			name = this.ast.newSimpleName(new String(tokens[0]));
-			int start = (int)(positions[0]>>>32);
-			int end = (int)(positions[0] & 0xFFFFFFFF);
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(tokens[0]));
+			final int start = (int)(positions[0]>>>32);
+			final int end = (int)(positions[0] & 0xFFFFFFFF);
 			name.setSourceRange(start, end - start + 1);
+			importDeclaration.setName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, importReference);
+			}
 		}
 		importDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
-		importDeclaration.setName(name);
 		importDeclaration.setOnDemand(onDemand);
 		int modifiers = importReference.modifiers;
 		if (modifiers != IConstants.AccDefault) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					importDeclaration.setFlags(importDeclaration.getFlags() | ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -2549,25 +2588,28 @@
 
 	public PackageDeclaration convertPackage(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration) {
 		org.eclipse.jdt.internal.compiler.ast.ImportReference importReference = compilationUnitDeclaration.currentPackage;
-		PackageDeclaration packageDeclaration = this.ast.newPackageDeclaration();
-		char[][] tokens = importReference.tokens;
-		int length = importReference.tokens.length;
+		final PackageDeclaration packageDeclaration = new PackageDeclaration(this.ast);
+		final char[][] tokens = importReference.tokens;
+		final int length = importReference.tokens.length;
 		long[] positions = importReference.sourcePositions;
-		int start = (int)(positions[0]>>>32);
-		int end = (int)(positions[length - 1] & 0xFFFFFFFF);
-		Name name = null;
 		if (length > 1) {
-			name = setQualifiedNameNameAndSourceRanges(tokens, positions, importReference);
+			packageDeclaration.setName(setQualifiedNameNameAndSourceRanges(tokens, positions, importReference));
 		} else {
-			name = this.ast.newSimpleName(new String(tokens[0]));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(tokens[0]));
+			int start = (int)(positions[0]>>>32);
+			int end = (int)(positions[length - 1] & 0xFFFFFFFF);
 			name.setSourceRange(start, end - start + 1);
+			packageDeclaration.setName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, compilationUnitDeclaration);
+			}
 		}
 		packageDeclaration.setSourceRange(importReference.declarationSourceStart, importReference.declarationEnd - importReference.declarationSourceStart + 1);
-		packageDeclaration.setName(name);
 		org.eclipse.jdt.internal.compiler.ast.Annotation[] annotations = importReference.annotations;
 		if (annotations != null) {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
+				case AST.JLS2_INTERNAL :
 					packageDeclaration.setFlags(packageDeclaration.getFlags() & ASTNode.MALFORMED);
 					break;
 				case AST.JLS3 :
@@ -2578,16 +2620,16 @@
 		}
 		if (this.resolveBindings) {
 			recordNodes(packageDeclaration, importReference);
-			recordNodes(name, compilationUnitDeclaration);
 		}
 		return packageDeclaration;
 	}
 	
 	private EnumDeclaration convertToEnumDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
 		checkCanceled();
-		EnumDeclaration enumDeclaration2 = this.ast.newEnumDeclaration();
+		final EnumDeclaration enumDeclaration2 = new EnumDeclaration(this.ast);
 		setModifiers(enumDeclaration2, typeDeclaration);
-		SimpleName typeName = this.ast.newSimpleName(new String(typeDeclaration.name));
+		final SimpleName typeName = new SimpleName(this.ast);
+		typeName.internalSetIdentifier(new String(typeDeclaration.name));
 		typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
 		enumDeclaration2.setName(typeName);
 		enumDeclaration2.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
@@ -2616,7 +2658,8 @@
 
 	protected FieldDeclaration convertToFieldDeclaration(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
 		VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(fieldDecl);
-		FieldDeclaration fieldDeclaration = this.ast.newFieldDeclaration(variableDeclarationFragment);
+		final FieldDeclaration fieldDeclaration = new FieldDeclaration(this.ast);
+		fieldDeclaration.fragments().add(variableDeclarationFragment);
 		if (this.resolveBindings) {
 			recordNodes(variableDeclarationFragment, fieldDecl);
 			variableDeclarationFragment.resolveBinding();
@@ -2630,7 +2673,7 @@
 	}
 
 	public ParenthesizedExpression convertToParenthesizedExpression(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
-		ParenthesizedExpression parenthesizedExpression = this.ast.newParenthesizedExpression();
+		final ParenthesizedExpression parenthesizedExpression = new ParenthesizedExpression(this.ast);
 		if (this.resolveBindings) {
 			recordNodes(parenthesizedExpression, expression);
 		}
@@ -2647,7 +2690,8 @@
 		
 	public Type convertToType(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
 		Name name = convert(reference);
-		SimpleType type = this.ast.newSimpleType(name);
+		final SimpleType type = new SimpleType(this.ast);
+		type.setName(name);
 		type.setSourceRange(name.getStartPosition(), name.getLength());
 		if (this.resolveBindings) {
 			this.recordNodes(type, reference);
@@ -2656,8 +2700,9 @@
 	}
 	
 	protected VariableDeclarationExpression convertToVariableDeclarationExpression(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
-		VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
-		VariableDeclarationExpression variableDeclarationExpression = this.ast.newVariableDeclarationExpression(variableDeclarationFragment);
+		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
+		final VariableDeclarationExpression variableDeclarationExpression = new VariableDeclarationExpression(this.ast);
+		variableDeclarationExpression.fragments().add(variableDeclarationFragment);
 		if (this.resolveBindings) {
 			recordNodes(variableDeclarationFragment, localDeclaration);
 		}
@@ -2671,9 +2716,10 @@
 	}
 
 	protected SingleVariableDeclaration convertToSingleVariableDeclaration(LocalDeclaration localDeclaration) {
-		SingleVariableDeclaration variableDecl = this.ast.newSingleVariableDeclaration();
+		final SingleVariableDeclaration variableDecl = new SingleVariableDeclaration(this.ast);
 		setModifiers(variableDecl, localDeclaration);
-		SimpleName name = this.ast.newSimpleName(new String(localDeclaration.name));
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(localDeclaration.name));
 		int start = localDeclaration.sourceStart;
 		int nameEnd = localDeclaration.sourceEnd;
 		name.setSourceRange(start, nameEnd - start + 1);
@@ -2698,20 +2744,24 @@
 	}
 	
 	protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
-		VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment();
-		SimpleName name = this.ast.newSimpleName(new String(fieldDeclaration.name));
+		final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(fieldDeclaration.name));
 		name.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.sourceEnd - fieldDeclaration.sourceStart + 1);
 		variableDeclarationFragment.setName(name);
-		int end = retrievePositionBeforeNextCommaOrSemiColon(fieldDeclaration.sourceEnd, fieldDeclaration.declarationSourceEnd);
+		int start = fieldDeclaration.sourceEnd;
+		if (fieldDeclaration.initialization != null) {
+			final Expression expression = convert(fieldDeclaration.initialization);
+			variableDeclarationFragment.setInitializer(expression);
+			start = expression.getStartPosition() + expression.getLength();
+		}
+		int end = retrievePositionBeforeNextCommaOrSemiColon(start, fieldDeclaration.declarationSourceEnd);
 		if (end == -1) {
 			variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, fieldDeclaration.declarationSourceEnd - fieldDeclaration.sourceStart + 1);
 			variableDeclarationFragment.setFlags(variableDeclarationFragment.getFlags() | ASTNode.MALFORMED);
 		} else {
 			variableDeclarationFragment.setSourceRange(fieldDeclaration.sourceStart, end - fieldDeclaration.sourceStart + 1);
 		}
-		if (fieldDeclaration.initialization != null) {
-			variableDeclarationFragment.setInitializer(convert(fieldDeclaration.initialization));
-		}
 		variableDeclarationFragment.setExtraDimensions(retrieveExtraDimension(fieldDeclaration.sourceEnd + 1, fieldDeclaration.declarationSourceEnd ));
 		if (this.resolveBindings) {
 			recordNodes(name, fieldDeclaration);
@@ -2722,8 +2772,9 @@
 	}
 
 	protected VariableDeclarationFragment convertToVariableDeclarationFragment(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
-		VariableDeclarationFragment variableDeclarationFragment = this.ast.newVariableDeclarationFragment();
-		SimpleName name = this.ast.newSimpleName(new String(localDeclaration.name));
+		final VariableDeclarationFragment variableDeclarationFragment = new VariableDeclarationFragment(this.ast);
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(localDeclaration.name));
 		name.setSourceRange(localDeclaration.sourceStart, localDeclaration.sourceEnd - localDeclaration.sourceStart + 1);
 		variableDeclarationFragment.setName(name);
 		int end = retrievePositionBeforeNextCommaOrSemiColon(localDeclaration.sourceEnd, this.compilationUnitSource.length);
@@ -2749,8 +2800,9 @@
 	}
 
 	protected VariableDeclarationStatement convertToVariableDeclarationStatement(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
-		VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
-		VariableDeclarationStatement variableDeclarationStatement = this.ast.newVariableDeclarationStatement(variableDeclarationFragment);
+		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
+		final VariableDeclarationStatement variableDeclarationStatement = new VariableDeclarationStatement(this.ast);
+		variableDeclarationStatement.fragments().add(variableDeclarationFragment);
 		if (this.resolveBindings) {
 			recordNodes(variableDeclarationFragment, localDeclaration);
 		}
@@ -2765,8 +2817,8 @@
 
 	public Type convertType(TypeReference typeReference) {
 		if (typeReference instanceof Wildcard) {
-			Wildcard wildcard = (Wildcard) typeReference;
-			WildcardType wildcardType = this.ast.newWildcardType();
+			final Wildcard wildcard = (Wildcard) typeReference;
+			final WildcardType wildcardType = new WildcardType(this.ast);
 			if (wildcard.bound != null) {
 				wildcardType.setBound(convertType(wildcard.bound), wildcard.kind == Wildcard.EXTENDS);
 			}
@@ -2793,29 +2845,37 @@
 				if (end == -1) {
 					end = sourceStart + length - 1;
 				}					
-				type = this.ast.newPrimitiveType(getPrimitiveTypeCode(name));
-				type.setSourceRange(sourceStart, end - sourceStart + 1);
+				final PrimitiveType primitiveType = new PrimitiveType(this.ast);
+				primitiveType.setPrimitiveTypeCode(getPrimitiveTypeCode(name));
+				primitiveType.setSourceRange(sourceStart, end - sourceStart + 1);
+				type = primitiveType;
 			} else if (typeReference instanceof ParameterizedSingleTypeReference) {
 				ParameterizedSingleTypeReference parameterizedSingleTypeReference = (ParameterizedSingleTypeReference) typeReference;
-				SimpleName simpleName = this.ast.newSimpleName(new String(name));
+				final SimpleName simpleName = new SimpleName(this.ast);
+				simpleName.internalSetIdentifier(new String(name));
 				int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
 				if (end == -1) {
 					end = sourceStart + length - 1;
 				}
 				simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 :
-						type = this.ast.newSimpleType(simpleName);
-						type.setFlags(type.getFlags() | ASTNode.MALFORMED);
-						type.setSourceRange(sourceStart, end - sourceStart + 1);
+					case AST.JLS2_INTERNAL :
+						SimpleType simpleType = new SimpleType(this.ast);
+						simpleType.setName(simpleName);
+						simpleType.setFlags(simpleType.getFlags() | ASTNode.MALFORMED);
+						simpleType.setSourceRange(sourceStart, end - sourceStart + 1);
+						type = simpleType;
 						if (this.resolveBindings) {
 							this.recordNodes(simpleName, typeReference);
 						}
 						break;
 					case AST.JLS3 :
-						SimpleType simpleType = this.ast.newSimpleType(simpleName);
+						simpleType = new SimpleType(this.ast);
+						simpleType.setName(simpleName);
 						simpleType.setSourceRange(simpleName.getStartPosition(), simpleName.getLength());
-						type = this.ast.newParameterizedType(simpleType);
+						final ParameterizedType parameterizedType = new ParameterizedType(this.ast);
+						parameterizedType.setType(simpleType);
+						type = parameterizedType;
 						TypeReference[] typeArguments = parameterizedSingleTypeReference.typeArguments;
 						if (typeArguments != null) {
 							Type type2 = null;
@@ -2835,7 +2895,8 @@
 						}
 				}
 			} else {
-				SimpleName simpleName = this.ast.newSimpleName(new String(name));
+				final SimpleName simpleName = new SimpleName(this.ast);
+				simpleName.internalSetIdentifier(new String(name));
 				// we need to search for the starting position of the first brace in order to set the proper length
 				// PR http://dev.eclipse.org/bugs/show_bug.cgi?id=10759
 				int end = retrieveEndOfElementTypeNamePosition(sourceStart, sourceStart + length);
@@ -2843,8 +2904,11 @@
 					end = sourceStart + length - 1;
 				}
 				simpleName.setSourceRange(sourceStart, end - sourceStart + 1);
-				type = this.ast.newSimpleType(simpleName);
+				final SimpleType simpleType = new SimpleType(this.ast);
+				simpleType.setName(simpleName);
+				type = simpleType;
 				type.setSourceRange(sourceStart, end - sourceStart + 1);
+				type = simpleType;
 				if (this.resolveBindings) {
 					this.recordNodes(simpleName, typeReference);
 				}
@@ -2852,6 +2916,14 @@
 			if (dimensions != 0) {
 				type = this.ast.newArrayType(type, dimensions);
 				type.setSourceRange(sourceStart, length);
+				ArrayType subarrayType = (ArrayType) type;
+				int index = dimensions - 1;
+				while (index > 0) {
+					subarrayType = (ArrayType) subarrayType.getComponentType();
+					int end = retrieveProperRightBracketPosition(index, sourceStart);
+					subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
+					index--;
+				}
 				if (this.resolveBindings) {
 					// store keys for inner types
 					completeRecord((ArrayType) type, typeReference);
@@ -2865,44 +2937,57 @@
 				long[] positions = parameterizedQualifiedTypeReference.sourcePositions;
 				sourceStart = (int)(positions[0]>>>32);
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 : {
+					case AST.JLS2_INTERNAL : {
 							char[][] name = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).getTypeName();
 							int nameLength = name.length;
 							sourceStart = (int)(positions[0]>>>32);
 							length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
 							Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
-							type = this.ast.newSimpleType(qualifiedName);
-							type.setSourceRange(sourceStart, length);
+							final SimpleType simpleType = new SimpleType(this.ast);
+							simpleType.setName(qualifiedName);
+							simpleType.setSourceRange(sourceStart, length);
+							type = simpleType;
 						}
 						break;
 					case AST.JLS3 :
 						if (typeArguments != null) {
 							int numberOfEnclosingType = 0;
+                            int startingIndex = 0;
+                            int endingIndex = 0;
 							for (int i = 0, max = typeArguments.length; i < max; i++) {
 								if (typeArguments[i] != null) {
 									numberOfEnclosingType++;
-								}
-							}
-							int startingIndex = 0;
-							int endingIndex = 0;
-							while (typeArguments[endingIndex] == null) {
-								endingIndex++;
+								} else if (numberOfEnclosingType == 0) {
+                                    endingIndex++;
+                                }
 							}
 							Name name = null;
 							if (endingIndex - startingIndex == 0) {
-								name = this.ast.newSimpleName(new String(tokens[startingIndex]));
-								recordPendingNameScopeResolution(name);
+								final SimpleName simpleName = new SimpleName(this.ast);
+								simpleName.internalSetIdentifier(new String(tokens[startingIndex]));
+								recordPendingNameScopeResolution(simpleName);
 								int start = (int)(positions[startingIndex]>>>32);
 								int end = (int) positions[startingIndex];
-								name.setSourceRange(start, end - start + 1);
+								simpleName.setSourceRange(start, end - start + 1);
+								simpleName.index = 1;
+								name = simpleName;
+								if (this.resolveBindings) {
+		 							recordNodes(simpleName, typeReference);
+								}
 							} else {
-								name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, startingIndex, endingIndex, typeReference);
+								name = this.setQualifiedNameNameAndSourceRanges(tokens, positions, endingIndex, typeReference);
 							}
-							SimpleType simpleType = this.ast.newSimpleType(name);
+							SimpleType simpleType = new SimpleType(this.ast);
+							simpleType.setName(name);
 							int start = (int)(positions[startingIndex]>>>32);
 							int end = (int) positions[endingIndex];
 							simpleType.setSourceRange(start, end - start + 1);
-							ParameterizedType parameterizedType = this.ast.newParameterizedType(simpleType);
+							ParameterizedType parameterizedType = new ParameterizedType(this.ast);
+							parameterizedType.setType(simpleType);
+                            if (this.resolveBindings) {
+                                recordNodes(simpleType, typeReference);
+                                recordNodes(parameterizedType, typeReference);
+                            }
 							start = simpleType.getStartPosition();
 							end = start + simpleType.getLength() - 1;
 							for (int i = 0, max = typeArguments[endingIndex].length; i < max; i++) {
@@ -2910,23 +2995,40 @@
 								parameterizedType.typeArguments().add(type2);
 								end = type2.getStartPosition() + type2.getLength() - 1;
 							}
+							int indexOfEnclosingType = 1;
+							parameterizedType.index = indexOfEnclosingType;
 							end = retrieveClosingAngleBracketPosition(end + 1);
 							length = end + 1;
 							parameterizedType.setSourceRange(start, end - start + 1);
 							startingIndex = endingIndex + 1;
 							Type currentType = parameterizedType;
 							while(startingIndex < typeArguments.length) {
-								SimpleName simpleName = this.ast.newSimpleName(new String(tokens[startingIndex]));
+								SimpleName simpleName = new SimpleName(this.ast);
+								simpleName.internalSetIdentifier(new String(tokens[startingIndex]));
+								simpleName.index = startingIndex + 1;
 								start = (int)(positions[startingIndex]>>>32);
 								end = (int) positions[startingIndex];
 								simpleName.setSourceRange(start, end - start + 1);
 								recordPendingNameScopeResolution(simpleName);
-								QualifiedType qualifiedType = this.ast.newQualifiedType(currentType, simpleName);							
+								QualifiedType qualifiedType = new QualifiedType(this.ast);
+								qualifiedType.setQualifier(currentType);
+								qualifiedType.setName(simpleName);	
+                                if (this.resolveBindings) {
+                                    recordNodes(simpleName, typeReference);
+                                    recordNodes(qualifiedType, typeReference);
+                                }
 								start = currentType.getStartPosition();
 								end = simpleName.getStartPosition() + simpleName.getLength() - 1;
 								qualifiedType.setSourceRange(start, end - start + 1);
+								indexOfEnclosingType++;
 								if (typeArguments[startingIndex] != null) {
-									ParameterizedType parameterizedType2 = this.ast.newParameterizedType(qualifiedType);
+	                               	qualifiedType.index = indexOfEnclosingType;
+									ParameterizedType parameterizedType2 = new ParameterizedType(this.ast);
+									parameterizedType2.setType(qualifiedType);
+ 									parameterizedType2.index = indexOfEnclosingType;
+                                   if (this.resolveBindings) {
+                                        recordNodes(parameterizedType2, typeReference);
+                                    }
 									for (int i = 0, max = typeArguments[startingIndex].length; i < max; i++) {
 										final Type type2 = convertType(typeArguments[startingIndex][i]);
 										parameterizedType2.typeArguments().add(type2);
@@ -2938,6 +3040,7 @@
 									currentType = parameterizedType2;
 								} else {
 									currentType = qualifiedType;
+                               		qualifiedType.index = indexOfEnclosingType;
 								}
 								startingIndex++;
 							}
@@ -2954,8 +3057,10 @@
 				long[] positions = ((org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference) typeReference).sourcePositions;
 				sourceStart = (int)(positions[0]>>>32);
 				length = (int)(positions[nameLength - 1] & 0xFFFFFFFF) - sourceStart + 1;
-				Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
-				type = this.ast.newSimpleType(qualifiedName);
+				final Name qualifiedName = this.setQualifiedNameNameAndSourceRanges(name, positions, typeReference);
+				final SimpleType simpleType = new SimpleType(this.ast);
+				simpleType.setName(qualifiedName);
+				type = simpleType;
 				type.setSourceRange(sourceStart, length);
 			}
 
@@ -2970,6 +3075,14 @@
 				} else {
 					type.setSourceRange(sourceStart, length);
 				}
+				ArrayType subarrayType = (ArrayType) type;
+				int index = dimensions - 1;
+				while (index > 0) {
+					subarrayType = (ArrayType) subarrayType.getComponentType();
+					end = retrieveProperRightBracketPosition(index, sourceStart);
+					subarrayType.setSourceRange(sourceStart, end - sourceStart + 1);
+					index--;
+				}
 			}
 		}
 		if (this.resolveBindings) {
@@ -2984,17 +3097,16 @@
 		int start = positions[0];
 		int end = positions[1];
 		if (positions[1]>0) { // Javadoc comments have positive end position
-			this.ast.newJavadoc();
 			Javadoc docComment = this.docParser.parse(positions);
 			if (docComment == null) return null;
 			comment = docComment;
 		} else {
 			end = -end;
 			if (positions[0]>0) { // Block comment have positive start position
-				comment = this.ast.newBlockComment();
+				comment = new BlockComment(this.ast);
 			} else { // Line comment have negative start and end position
 				start = -start;
-				comment = this.ast.newLineComment();
+				comment = new LineComment(this.ast);
 			}
 			comment.setSourceRange(start, end - start);
 		}
@@ -3002,7 +3114,7 @@
 	}
 	
 	protected Statement createFakeEmptyStatement(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
-		EmptyStatement emptyStatement = this.ast.newEmptyStatement();
+		EmptyStatement emptyStatement = new EmptyStatement(this.ast);
 		emptyStatement.setFlags(emptyStatement.getFlags() | ASTNode.MALFORMED);
 		int start = statement.sourceStart;
 		int end = statement.sourceEnd;
@@ -3013,8 +3125,8 @@
 	 * @return a new modifier
 	 */
 	private Modifier createModifier(ModifierKeyword keyword) {
-		Modifier modifier;
-		modifier = this.ast.newModifier(keyword);
+		final Modifier modifier = new Modifier(this.ast);
+		modifier.setKeyword(keyword);
 		int start = this.scanner.getCurrentTokenStartPosition();
 		int end = this.scanner.getCurrentTokenEndPosition();
 		modifier.setSourceRange(start, end - start + 1);
@@ -3286,14 +3398,11 @@
 			if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference) {
 				org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = (org.eclipse.jdt.internal.compiler.ast.TypeReference) compilerNode;
 				if (name.isQualifiedName()) {
-					int count = 0;
 					SimpleName simpleName = null;
 					while (name.isQualifiedName()) {
 						simpleName = ((QualifiedName) name).getName();
 						recordNodes(simpleName, typeRef);
-						simpleName.index = count++;
 						name = ((QualifiedName) name).getQualifier();
-						name.index = count;
 						recordNodes(name, typeRef);
 					}
 				}
@@ -3352,7 +3461,7 @@
 					org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = null;
 					if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression) {
 						typeRef = ((org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression)compilerNode).type;
-						if (typeRef != null) recordNodes(name, typeRef);
+						if (typeRef != null) recordNodes(name, compilerNode);
 					} 
 					else if (compilerNode instanceof org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend) {
 						org.eclipse.jdt.internal.compiler.ast.Expression expression = ((org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend)compilerNode).receiver;
@@ -3377,12 +3486,13 @@
 						if (expression instanceof JavadocArgumentExpression) {
 							JavadocArgumentExpression argExpr = (JavadocArgumentExpression) expression;
 							org.eclipse.jdt.internal.compiler.ast.TypeReference typeRef = argExpr.argument.type;
+							if (this.ast.apiLevel >= AST.JLS3) param.setVarargs(argExpr.argument.isVarArgs());
 							recordNodes(param.getType(), typeRef);
 							if (param.getType().isSimpleType()) {
-								SimpleType type = (SimpleType)param.getType();
-								recordName(type.getName(), typeRef);
+								recordName(((SimpleType)param.getType()).getName(), typeRef);
 							} else if (param.getType().isArrayType()) {
 								Type type = ((ArrayType) param.getType()).getElementType();
+								recordNodes(type, typeRef);
 								if (type.isSimpleType()) {
 									recordName(((SimpleType)type).getName(), typeRef);
 								}
@@ -4103,8 +4213,8 @@
 	 */
 	protected void setModifiers(FieldDeclaration fieldDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDecl) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
-				fieldDeclaration.setModifiers(fieldDecl.modifiers & CompilerModifiers.AccJustFlag);
+			case AST.JLS2_INTERNAL :
+				fieldDeclaration.internalSetModifiers(fieldDecl.modifiers & CompilerModifiers.AccJustFlag);
 				if (fieldDecl.annotations != null) {
 					fieldDeclaration.setFlags(fieldDeclaration.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4121,8 +4231,8 @@
 	 */
 	protected void setModifiers(Initializer initializer, org.eclipse.jdt.internal.compiler.ast.Initializer oldInitializer) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2: 
-				initializer.setModifiers(oldInitializer.modifiers & CompilerModifiers.AccJustFlag);
+			case AST.JLS2_INTERNAL: 
+				initializer.internalSetModifiers(oldInitializer.modifiers & CompilerModifiers.AccJustFlag);
 				if (oldInitializer.annotations != null) {
 					initializer.setFlags(initializer.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4138,8 +4248,8 @@
 	 */
 	protected void setModifiers(MethodDeclaration methodDecl, AbstractMethodDeclaration methodDeclaration) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
-				methodDecl.setModifiers(methodDeclaration.modifiers & CompilerModifiers.AccJustFlag);
+			case AST.JLS2_INTERNAL :
+				methodDecl.internalSetModifiers(methodDeclaration.modifiers & CompilerModifiers.AccJustFlag);
 				if (methodDeclaration.annotations != null) {
 					methodDecl.setFlags(methodDecl.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4156,8 +4266,8 @@
 	 */
 	protected void setModifiers(SingleVariableDeclaration variableDecl, Argument argument) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
-				variableDecl.setModifiers(argument.modifiers & CompilerModifiers.AccJustFlag);
+			case AST.JLS2_INTERNAL :
+				variableDecl.internalSetModifiers(argument.modifiers & CompilerModifiers.AccJustFlag);
 				if (argument.annotations != null) {
 					variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4224,8 +4334,8 @@
 	
 	protected void setModifiers(SingleVariableDeclaration variableDecl, LocalDeclaration localDeclaration) {
 		switch(this.ast.apiLevel) {
-		case AST.JLS2 :
-			variableDecl.setModifiers(localDeclaration.modifiers & CompilerModifiers.AccJustFlag);
+		case AST.JLS2_INTERNAL :
+			variableDecl.internalSetModifiers(localDeclaration.modifiers & CompilerModifiers.AccJustFlag);
 			if (localDeclaration.annotations != null) {
 				variableDecl.setFlags(variableDecl.getFlags() | ASTNode.MALFORMED);
 			}
@@ -4296,11 +4406,11 @@
 	 */
 	protected void setModifiers(TypeDeclaration typeDecl, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
 		switch(this.ast.apiLevel) { 
-			case AST.JLS2 :
+			case AST.JLS2_INTERNAL :
 				int modifiers = typeDeclaration.modifiers;
 				modifiers &= ~IConstants.AccInterface; // remove AccInterface flags
 				modifiers &= CompilerModifiers.AccJustFlag;
-				typeDecl.setModifiers(modifiers);
+				typeDecl.internalSetModifiers(modifiers);
 				if (typeDeclaration.annotations != null) {
 					typeDecl.setFlags(typeDecl.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4317,10 +4427,10 @@
 	 */
 	protected void setModifiers(VariableDeclarationExpression variableDeclarationExpression, LocalDeclaration localDeclaration) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
+			case AST.JLS2_INTERNAL :
 				int modifiers = localDeclaration.modifiers & CompilerModifiers.AccJustFlag;
 				modifiers &= ~CompilerModifiers.AccBlankFinal;
-				variableDeclarationExpression.setModifiers(modifiers);
+				variableDeclarationExpression.internalSetModifiers(modifiers);
 				if (localDeclaration.annotations != null) {
 					variableDeclarationExpression.setFlags(variableDeclarationExpression.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4391,10 +4501,10 @@
 	 */
 	protected void setModifiers(VariableDeclarationStatement variableDeclarationStatement, LocalDeclaration localDeclaration) {
 		switch(this.ast.apiLevel) {
-			case AST.JLS2 :
+			case AST.JLS2_INTERNAL :
 				int modifiers = localDeclaration.modifiers & CompilerModifiers.AccJustFlag;
 				modifiers &= ~CompilerModifiers.AccBlankFinal;
-				variableDeclarationStatement.setModifiers(modifiers);
+				variableDeclarationStatement.internalSetModifiers(modifiers);
 				if (localDeclaration.annotations != null) {
 					variableDeclarationStatement.setFlags(variableDeclarationStatement.getFlags() | ASTNode.MALFORMED);
 				}
@@ -4461,18 +4571,22 @@
 
 	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
 		int length = typeName.length;
-		SimpleName firstToken = this.ast.newSimpleName(new String(typeName[0]));
-		firstToken.index = length - 1;
+		final SimpleName firstToken = new SimpleName(this.ast);
+		firstToken.internalSetIdentifier(new String(typeName[0]));
+		firstToken.index = 1;
 		int start0 = (int)(positions[0]>>>32);
 		int start = start0;
 		int end = (int)(positions[0] & 0xFFFFFFFF);
 		firstToken.setSourceRange(start, end - start + 1);
-		SimpleName secondToken = this.ast.newSimpleName(new String(typeName[1]));
-		secondToken.index = length - 2;
+		final SimpleName secondToken = new SimpleName(this.ast);
+		secondToken.internalSetIdentifier(new String(typeName[1]));
+		secondToken.index = 2;
 		start = (int)(positions[1]>>>32);
 		end = (int)(positions[1] & 0xFFFFFFFF);
 		secondToken.setSourceRange(start, end - start + 1);
-		QualifiedName qualifiedName = this.ast.newQualifiedName(firstToken, secondToken);
+		QualifiedName qualifiedName = new QualifiedName(this.ast);
+		qualifiedName.setQualifier(firstToken);
+		qualifiedName.setName(secondToken);
 		if (this.resolveBindings) {
 			recordNodes(qualifiedName, node);
 			recordPendingNameScopeResolution(qualifiedName);
@@ -4481,16 +4595,20 @@
 			recordPendingNameScopeResolution(firstToken);
 			recordPendingNameScopeResolution(secondToken);
 		}
-		qualifiedName.index = length - 2;
+		qualifiedName.index = 2;
 		qualifiedName.setSourceRange(start0, end - start0 + 1);
 		SimpleName newPart = null;
 		for (int i = 2; i < length; i++) {
-			newPart = this.ast.newSimpleName(new String(typeName[i]));
-			newPart.index = length - i - 1;
+			newPart = new SimpleName(this.ast);
+			newPart.internalSetIdentifier(new String(typeName[i]));
+			newPart.index = i + 1;
 			start = (int)(positions[i]>>>32);
 			end = (int)(positions[i] & 0xFFFFFFFF);
 			newPart.setSourceRange(start,  end - start + 1);
-			qualifiedName = this.ast.newQualifiedName(qualifiedName, newPart);
+			QualifiedName qualifiedName2 = new QualifiedName(this.ast);
+			qualifiedName2.setQualifier(qualifiedName);
+			qualifiedName2.setName(newPart);
+			qualifiedName = qualifiedName2;
 			qualifiedName.index = newPart.index;
 			qualifiedName.setSourceRange(start0, end - start0 + 1);
 			if (this.resolveBindings) {
@@ -4508,20 +4626,24 @@
 		return name;
 	}
 	
-	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int startingIndex, int endingIndex, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
-		int length = endingIndex - startingIndex + 1;
-		SimpleName firstToken = this.ast.newSimpleName(new String(typeName[startingIndex]));
-		firstToken.index = startingIndex;
-		int start0 = (int)(positions[startingIndex]>>>32);
+	protected QualifiedName setQualifiedNameNameAndSourceRanges(char[][] typeName, long[] positions, int endingIndex, org.eclipse.jdt.internal.compiler.ast.ASTNode node) {
+ 		int length = endingIndex + 1;
+		final SimpleName firstToken = new SimpleName(this.ast);
+		firstToken.internalSetIdentifier(new String(typeName[0]));
+		firstToken.index = 1;
+		int start0 = (int)(positions[0]>>>32);
 		int start = start0;
-		int end = (int) positions[startingIndex];
+		int end = (int) positions[0];
 		firstToken.setSourceRange(start, end - start + 1);
-		SimpleName secondToken = this.ast.newSimpleName(new String(typeName[startingIndex + 1]));
-		secondToken.index = startingIndex + 1;
-		start = (int)(positions[startingIndex + 1]>>>32);
-		end = (int) positions[startingIndex + 1];
+		final SimpleName secondToken = new SimpleName(this.ast);
+		secondToken.internalSetIdentifier(new String(typeName[1]));
+		secondToken.index = 2;
+		start = (int)(positions[1]>>>32);
+		end = (int) positions[1];
 		secondToken.setSourceRange(start, end - start + 1);
-		QualifiedName qualifiedName = this.ast.newQualifiedName(firstToken, secondToken);
+		QualifiedName qualifiedName = new QualifiedName(this.ast);
+		qualifiedName.setQualifier(firstToken);
+		qualifiedName.setName(secondToken);
 		if (this.resolveBindings) {
 			recordNodes(qualifiedName, node);
 			recordPendingNameScopeResolution(qualifiedName);
@@ -4530,16 +4652,20 @@
 			recordPendingNameScopeResolution(firstToken);
 			recordPendingNameScopeResolution(secondToken);
 		}
-		qualifiedName.index = startingIndex + 1;
+		qualifiedName.index = 2;
 		qualifiedName.setSourceRange(start0, end - start0 + 1);
 		SimpleName newPart = null;
 		for (int i = 2; i < length; i++) {
-			newPart = this.ast.newSimpleName(new String(typeName[i]));
-			newPart.index = startingIndex + i;
+			newPart = new SimpleName(this.ast);
+			newPart.internalSetIdentifier(new String(typeName[i]));
+			newPart.index = i + 1;
 			start = (int)(positions[i]>>>32);
 			end = (int) positions[i];
 			newPart.setSourceRange(start,  end - start + 1);
-			qualifiedName = this.ast.newQualifiedName(qualifiedName, newPart);
+			QualifiedName qualifiedName2 = new QualifiedName(this.ast);
+			qualifiedName2.setQualifier(qualifiedName);
+			qualifiedName2.setName(newPart);
+			qualifiedName = qualifiedName2;
 			qualifiedName.index = newPart.index;
 			qualifiedName.setSourceRange(start0, end - start0 + 1);
 			if (this.resolveBindings) {
@@ -4549,34 +4675,33 @@
 				recordPendingNameScopeResolution(newPart);
 			}
 		}
-		QualifiedName name = qualifiedName;
-		if (this.resolveBindings) {
-			recordNodes(name, node);
-			recordPendingNameScopeResolution(name);
-		}
-		return name;
+        if (newPart == null && this.resolveBindings) {
+            recordNodes(qualifiedName, node);
+            recordPendingNameScopeResolution(qualifiedName);
+        }
+		return qualifiedName;
 	}
 	
 	protected void setTypeNameForAnnotation(org.eclipse.jdt.internal.compiler.ast.Annotation compilerAnnotation, Annotation annotation) {
 		TypeReference typeReference = compilerAnnotation.type;
-		Name name;
 		if (typeReference instanceof QualifiedTypeReference) {
 			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) typeReference;
 			char[][] tokens = qualifiedTypeReference.tokens;
 			long[] positions = qualifiedTypeReference.sourcePositions;
 			// QualifiedName
-			name = setQualifiedNameNameAndSourceRanges(tokens, positions, compilerAnnotation);
+			annotation.setTypeName(setQualifiedNameNameAndSourceRanges(tokens, positions, typeReference));
 		} else {
 			SingleTypeReference singleTypeReference = (SingleTypeReference) typeReference;
-			name = this.ast.newSimpleName(new String(singleTypeReference.token));
+			final SimpleName name = new SimpleName(this.ast);
+			name.internalSetIdentifier(new String(singleTypeReference.token));
 			int start = singleTypeReference.sourceStart;
 			int end = singleTypeReference.sourceEnd;
 			name.setSourceRange(start, end - start + 1);
+			annotation.setTypeName(name);
+			if (this.resolveBindings) {
+				recordNodes(name, typeReference);
+			}
 		}
-		if (this.resolveBindings) {
-			recordNodes(name, compilerAnnotation);
-		}
-		annotation.setTypeName(name);
 	}
 	
 	protected void setTypeForField(FieldDeclaration fieldDeclaration, Type type, int extraDimension) {
@@ -4632,8 +4757,8 @@
 					elementType.setParent(null, null);
 					this.ast.getBindingResolver().updateKey(type, elementType);
 					switch(this.ast.apiLevel) {
-						case AST.JLS2 :
-							methodDeclaration.setReturnType(elementType);
+						case AST.JLS2_INTERNAL :
+							methodDeclaration.internalSetReturnType(elementType);
 							break;
 						case AST.JLS3 :
 							methodDeclaration.setReturnType2(elementType);
@@ -4653,8 +4778,8 @@
 					subarrayType.setParent(null, null);
 					updateInnerPositions(subarrayType, remainingDimensions);
 					switch(this.ast.apiLevel) {
-						case AST.JLS2 :
-							methodDeclaration.setReturnType(subarrayType);
+						case AST.JLS2_INTERNAL :
+							methodDeclaration.internalSetReturnType(subarrayType);
 							break;
 						case AST.JLS3 :
 							methodDeclaration.setReturnType2(subarrayType);
@@ -4664,8 +4789,8 @@
 				}
 			} else {
 				switch(this.ast.apiLevel) {
-					case AST.JLS2 :
-						methodDeclaration.setReturnType(type);
+					case AST.JLS2_INTERNAL :
+						methodDeclaration.internalSetReturnType(type);
 						break;
 					case AST.JLS3 :
 						methodDeclaration.setReturnType2(type);
@@ -4674,8 +4799,8 @@
 			}
 		} else {
 			switch(this.ast.apiLevel) {
-				case AST.JLS2 :
-					methodDeclaration.setReturnType(type);
+				case AST.JLS2_INTERNAL :
+					methodDeclaration.internalSetReturnType(type);
 					break;
 				case AST.JLS3 :
 					methodDeclaration.setReturnType2(type);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
index 5892837..c7631d1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -172,7 +172,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(AnnotationTypeDeclaration node, Object other) {
 		if (!(other instanceof AnnotationTypeDeclaration)) {
@@ -199,7 +199,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(AnnotationTypeMemberDeclaration node, Object other) {
 		if (!(other instanceof AnnotationTypeMemberDeclaration)) {
@@ -407,6 +407,11 @@
 	 * other object is a node of the same type. Subclasses may override
 	 * this method as needed.
 	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
 	 * 
 	 * @param node the node
 	 * @param other the other object, or <code>null</code>
@@ -556,8 +561,8 @@
 		}
 		ClassInstanceCreation o = (ClassInstanceCreation) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
-			if (!safeSubtreeMatch(node.getName(), o.getName())) {
+		if (level == AST.JLS2_INTERNAL) {
+			if (!safeSubtreeMatch(node.internalGetName(), o.internalGetName())) {
 				return false;
 			}
 		}
@@ -734,7 +739,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(EnhancedForStatement node, Object other) {
 		if (!(other instanceof EnhancedForStatement)) {
@@ -754,19 +759,13 @@
 	 * other object is a node of the same type with structurally isomorphic
 	 * child subtrees. Subclasses may override this method as needed.
 	 * </p>
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @param node the node
 	 * @param other the other object, or <code>null</code>
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(EnumConstantDeclaration node, Object other) {
 		if (!(other instanceof EnumConstantDeclaration)) {
@@ -778,12 +777,9 @@
 				&& safeSubtreeListMatch(node.modifiers(), o.modifiers())
 				&& safeSubtreeMatch(node.getName(), o.getName())
 				&& safeSubtreeListMatch(node.arguments(), o.arguments())
-				&& safeSubtreeListMatch(
-					node.obsoleteBodyDeclarations(),
-					o.obsoleteBodyDeclarations()))
 				&& safeSubtreeMatch(
 					node.getAnonymousClassDeclaration(),
-					o.getAnonymousClassDeclaration());
+					o.getAnonymousClassDeclaration()));
 	}
 	
 	/**
@@ -799,7 +795,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(EnumDeclaration node, Object other) {
 		if (!(other instanceof EnumDeclaration)) {
@@ -883,7 +879,7 @@
 		}
 		FieldDeclaration o = (FieldDeclaration) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
@@ -1057,7 +1053,7 @@
 		}
 		Initializer o = (Initializer) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
@@ -1117,7 +1113,7 @@
 	 * @deprecated mark deprecated to hide deprecated usage
 	 */
 	private boolean compareDeprecatedComment(Javadoc first, Javadoc second) {
-		if (first.getAST().apiLevel == AST.JLS2) {
+		if (first.getAST().apiLevel == AST.JLS2_INTERNAL) {
 			return safeEquals(first.getComment(), second.getComment());
 		} else {
 			return true;
@@ -1155,6 +1151,11 @@
 	 * other object is a node of the same type. Subclasses may override
 	 * this method as needed.
 	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
 	 * 
 	 * @param node the node
 	 * @param other the other object, or <code>null</code>
@@ -1183,7 +1184,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(MarkerAnnotation node, Object other) {
 		if (!(other instanceof MarkerAnnotation)) {
@@ -1231,7 +1232,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(MemberValuePair node, Object other) {
 		if (!(other instanceof MemberValuePair)) {
@@ -1288,6 +1289,12 @@
 			return false;
 		}
 		MethodRefParameter o = (MethodRefParameter) other;
+		int level = node.getAST().apiLevel;
+		if (level >= AST.JLS3) {
+			if (node.isVarargs() != o.isVarargs()) {
+				return false;
+			}
+		}
 		return (
 				safeSubtreeMatch(node.getType(), o.getType())
 				&& safeSubtreeMatch(node.getName(), o.getName()));
@@ -1321,11 +1328,11 @@
 		}
 		MethodDeclaration o = (MethodDeclaration) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
-			if (!safeSubtreeMatch(node.getReturnType(), o.getReturnType())) {
+			if (!safeSubtreeMatch(node.internalGetReturnType(), o.internalGetReturnType())) {
 				return false;
 			}
 		}
@@ -1394,7 +1401,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(Modifier node, Object other) {
 		if (!(other instanceof Modifier)) {
@@ -1417,7 +1424,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(NormalAnnotation node, Object other) {
 		if (!(other instanceof NormalAnnotation)) {
@@ -1514,7 +1521,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(ParameterizedType node, Object other) {
 		if (!(other instanceof ParameterizedType)) {
@@ -1654,7 +1661,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(QualifiedType node, Object other) {
 		if (!(other instanceof QualifiedType)) {
@@ -1745,7 +1752,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(SingleMemberAnnotation node, Object other) {
 		if (!(other instanceof SingleMemberAnnotation)) {
@@ -1780,7 +1787,7 @@
 		}
 		SingleVariableDeclaration o = (SingleVariableDeclaration) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
@@ -2112,14 +2119,14 @@
 		}
 		TypeDeclaration o = (TypeDeclaration) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
-			if (!safeSubtreeMatch(node.getSuperclass(), o.getSuperclass())) {
+			if (!safeSubtreeMatch(node.internalGetSuperclass(), o.internalGetSuperclass())) {
 				return false;
 			}
-			if (!safeSubtreeListMatch(node.superInterfaces(), o.superInterfaces())) {
+			if (!safeSubtreeListMatch(node.internalSuperInterfaces(), o.internalSuperInterfaces())) {
 				return false;
 			}
 		}
@@ -2201,7 +2208,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(TypeParameter node, Object other) {
 		if (!(other instanceof TypeParameter)) {
@@ -2232,7 +2239,7 @@
 		}
 		VariableDeclarationExpression o = (VariableDeclarationExpression) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
@@ -2294,7 +2301,7 @@
 		}
 		VariableDeclarationStatement o = (VariableDeclarationStatement) other;
 		int level = node.getAST().apiLevel;
-		if (level == AST.JLS2) {
+		if (level == AST.JLS2_INTERNAL) {
 			if (node.getModifiers() != o.getModifiers()) {
 				return false;
 			}
@@ -2345,7 +2352,7 @@
 	 * @return <code>true</code> if the subtree matches, or 
 	 *   <code>false</code> if they do not match or the other object has a
 	 *   different node type or is <code>null</code>
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean match(WildcardType node, Object other) {
 		if (!(other instanceof WildcardType)) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
index faccc74..2ecebe1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -647,7 +647,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>EnhancedForStatement</code>.
 	 * @see EnhancedForStatement
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int ENHANCED_FOR_STATEMENT = 70;
 
@@ -655,7 +655,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>EnumDeclaration</code>.
 	 * @see EnumDeclaration
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int ENUM_DECLARATION = 71;
 	
@@ -663,7 +663,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>EnumConstantDeclaration</code>.
 	 * @see EnumConstantDeclaration
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int ENUM_CONSTANT_DECLARATION = 72;
 	
@@ -671,7 +671,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>TypeParameter</code>.
 	 * @see TypeParameter
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int TYPE_PARAMETER = 73;
 
@@ -679,7 +679,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>ParameterizedType</code>.
 	 * @see ParameterizedType
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int PARAMETERIZED_TYPE = 74;
 
@@ -687,7 +687,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>QualifiedType</code>.
 	 * @see QualifiedType
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int QUALIFIED_TYPE = 75;
 	
@@ -695,7 +695,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>WildcardType</code>.
 	 * @see WildcardType
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int WILDCARD_TYPE = 76;
 	
@@ -703,7 +703,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>NormalAnnotation</code>.
 	 * @see NormalAnnotation
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int NORMAL_ANNOTATION = 77;
 	
@@ -711,7 +711,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>MarkerAnnotation</code>.
 	 * @see MarkerAnnotation
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int MARKER_ANNOTATION = 78;
 	
@@ -719,7 +719,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>SingleMemberAnnotation</code>.
 	 * @see SingleMemberAnnotation
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int SINGLE_MEMBER_ANNOTATION = 79;
 	
@@ -727,7 +727,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>MemberValuePair</code>.
 	 * @see MemberValuePair
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int MEMBER_VALUE_PAIR = 80;
 	
@@ -735,7 +735,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>AnnotationTypeDeclaration</code>.
 	 * @see AnnotationTypeDeclaration
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int ANNOTATION_TYPE_DECLARATION = 81;
 	
@@ -743,7 +743,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>AnnotationTypeMemberDeclaration</code>.
 	 * @see AnnotationTypeMemberDeclaration
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = 82;
 	
@@ -751,7 +751,7 @@
 	 * Node type constant indicating a node of type 
 	 * <code>Modifier</code>.
 	 * @see Modifier
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final int MODIFIER = 83;
 	
@@ -1754,7 +1754,7 @@
 	 * @since 3.0
      */
 	final void unsupportedIn2() {
-	  if (this.ast.apiLevel == AST.JLS2) {
+	  if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 	  	throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
 	  }
 	}
@@ -1767,7 +1767,7 @@
 	 * @since 3.0
      */
 	final void supportedOnlyIn2() {
-	  if (this.ast.apiLevel != AST.JLS2) {
+	  if (this.ast.apiLevel != AST.JLS2_INTERNAL) {
 	  	throw new UnsupportedOperationException("Operation only supported in JLS2 AST"); //$NON-NLS-1$
 	  }
 	}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
index 9e4bd86..ba7e715 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,6 +15,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
@@ -37,7 +38,7 @@
  * Example: Create basic AST from source string
  * <pre>
  * char[] source = ...;
- * ASTParser parser = ASTParser.newParser(AST.JLS2);  // handles JLS2 (J2SE 1.4)
+ * ASTParser parser = ASTParser.newParser(AST.JLS3);  // handles JDK 1.0, 1.1, 1.2, 1.3, 1.4, 1.5
  * parser.setSource(source);
  * CompilationUnit result = (CompilationUnit) parser.createAST(null);
  * </pre>
@@ -99,11 +100,6 @@
 	/**
 	 * Creates a new object for creating a Java abstract syntax tree
      * (AST) following the specified set of API rules.
-     * <p>
-     * <b>NOTE:</b>In Eclipse 3.0, there is no parser support for
-     * AST.JLS3. This support is planned for the follow-on release of
-     * Eclipse which includes support for J2SE 1.5.
-     * </p>
      *  
  	 * @param level the API level; one of the LEVEL constants
      * declared on <code>AST</code>
@@ -200,7 +196,7 @@
      * declared on <code>AST</code>
 	 */
 	ASTParser(int level) {
-		if ((level != AST.JLS2)
+		if ((level != AST.JLS2_INTERNAL)
 			&& (level != AST.JLS3)) {
 			throw new IllegalArgumentException();
 		}
@@ -344,16 +340,16 @@
 	 * When the parse is successful the result returned includes the ASTs for the
 	 * requested source:
 	 * <ul>
-	 * <li>{@link #K_COMPILATION_UNIT}: The result node
+	 * <li>{@link #K_COMPILATION_UNIT K_COMPILATION_UNIT}: The result node
 	 * is a {@link CompilationUnit}.</li>
-	 * <li>{@link #K_CLASS_BODY_DECLARATIONS}: The result node
+	 * <li>{@link #K_CLASS_BODY_DECLARATIONS K_CLASS_BODY_DECLARATIONS}: The result node
 	 * is a {@link TypeDeclaration} whose
 	 * {@link TypeDeclaration#bodyDeclarations() bodyDeclarations}
 	 * are the new trees. Other aspects of the type declaration are unspecified.</li>
-	 * <li>{@link #K_STATEMENTS}: The result node is a
+	 * <li>{@link #K_STATEMENTS K_STATEMENTS}: The result node is a
 	 * {@link Block Block} whose {@link Block#statements() statements}
 	 * are the new trees. Other aspects of the block are unspecified.</li>
-	 * <li>{@link #K_EXPRESSION}: The result node is a subclass of
+	 * <li>{@link #K_EXPRESSION K_EXPRESSION}: The result node is a subclass of
 	 * {@link Expression Expression}. Other aspects of the expression are unspecified.</li>
 	 * </ul>
 	 * The resulting AST node is rooted under (possibly contrived)
@@ -620,9 +616,13 @@
      * units being processed. When bindings are being resolved,
      * the keys and corresponding bindings (or <code>null</code> if none) are
      * passed to <code>ASTRequestor.acceptBinding</code>. Note that binding keys
-     * are looked up after all <code>ASTRequestor.acceptAST</code> callbacks
-     * have been made. No <code>ASTRequestor.acceptBinding</code> callbacks are
-     * made unless bindings are being resolved.
+     * for elements outside the set of compilation units being processed are looked up 
+     * after all <code>ASTRequestor.acceptAST</code> callbacks have been made. 
+     * Binding keys for elements inside the set of compilation units being processed
+     * are looked up and reported right after the corresponding 
+     * <code>ASTRequestor.acceptAST</code> callback has been made.
+     * No <code>ASTRequestor.acceptBinding</code> callbacks are made unless 
+     * bindings are being resolved.
      * </p>
      * <p>
      * A successful call to this method returns all settings to their
@@ -653,6 +653,56 @@
 		}
 	}
 	
+	/**
+     * Creates bindings for a batch of Java elements. These elements are either 
+     * enclosed in {@link ICompilationUnit}s or in {@link IClassFile}s.
+     * <p>
+     * All enclosing compilation units and class files must
+     * come from the same Java project, which must be set beforehand
+     * with <code>setProject</code>.
+     * </p>
+     * <p>
+     * All elements must exist. If one doesn't exist, an <code>IllegalStateException</code>
+     * is thrown.
+     * </p>
+     * <p>
+     * The returned array has the same size as the given elements array. At a given position
+     * it contains the binding of the corresponding Java element, or <code>null</code> 
+     * if no binding could be created. 
+     * </p>
+	 * <p>
+	 * Note also the following parser parameters are used, regardless of what
+	 * may have been specified:
+	 * <ul>
+	 * <li>The {@linkplain #setResolveBindings(boolean) binding resolution flag} is <code>true</code<</li>
+	 * <li>The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code></li>
+	 * <li>The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code></li>
+	 * <li>The {@linkplain #setFocalPosition(int) focal position} is not set</li>
+	 * </ul>
+	 * </p>
+     * <p>
+     * A successful call to this method returns all settings to their
+     * default values so the object is ready to be reused.
+     * </p>
+     * 
+     * @param elements the Java elements to create bindings for
+     * @return the bindings for the given Java elements, possibly containing <code>null</code>s
+     *              if some bindings could not be created
+	 * @exception IllegalStateException if the settings provided
+	 * are insufficient, contradictory, or otherwise unsupported
+	 * @since 3.1
+     */
+	public IBinding[] createBindings(IJavaElement[] elements, IProgressMonitor monitor) {
+		try {
+			if (this.project == null)
+				throw new IllegalStateException("project not specified"); //$NON-NLS-1$
+			return CompilationUnitResolver.resolve(elements, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, monitor);
+		} finally {
+	   	   // re-init defaults to allow reuse (and avoid leaking)
+	   	   initializeDefaults();
+		}
+	}
+	
 	private ASTNode internalCreateAST(IProgressMonitor monitor) {
 		boolean needToResolveBindings = this.resolveBindings;
 		switch(this.astKind) {
@@ -671,12 +721,14 @@
 				try {
 					NodeSearcher searcher = null;
 					org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = null;
+					IJavaElement element = null;
 					if (this.compilationUnitSource != null) {
 						sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.compilationUnitSource;
 						// use a BasicCompilation that caches the source instead of using the compilationUnitSource directly 
 						// (if it is a working copy, the source can change between the parse and the AST convertion)
 						// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=75632)
 						sourceUnit = new BasicCompilationUnit(sourceUnit.getContents(), sourceUnit.getPackageName(), new String(sourceUnit.getFileName()), this.project);
+						element = this.compilationUnitSource;
 					} else if (this.classFileSource != null) {
 						try {
 							String sourceString = this.classFileSource.getSource();
@@ -688,6 +740,7 @@
 							IBinaryType binaryType = (IBinaryType) type.getElementInfo();
 							String fileName = new String(binaryType.getFileName()); // file name is used to recreate the Java element, so it has to be the .class file name
 							sourceUnit = new BasicCompilationUnit(sourceString.toCharArray(), Util.toCharArrays(packageFragment.names), fileName, this.project);
+							element = this.classFileSource;
 						} catch(JavaModelException e) {
 							// an error occured accessing the java element
 							throw new IllegalStateException();
@@ -726,7 +779,7 @@
 								this.compilerOptions);
 						needToResolveBindings = false;
 					}
-					return CompilationUnitResolver.convert(
+					CompilationUnit result = CompilationUnitResolver.convert(
 						compilationUnitDeclaration, 
 						sourceUnit.getContents(),
 						this.apiLevel, 
@@ -735,6 +788,8 @@
 						this.compilationUnitSource == null ? this.workingCopyOwner : this.compilationUnitSource.getOwner(),
 						needToResolveBindings ? new DefaultBindingResolver.BindingTables() : null, 
 						monitor);
+					result.setJavaElement(element);
+					return result;
 				} finally {
 					if (compilationUnitDeclaration != null && this.resolveBindings) {
 						compilationUnitDeclaration.cleanUp();
@@ -969,4 +1024,4 @@
 				}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java
index c0eedfe..d5a1404 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java
index 9842f01..f423a29 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTSyntaxErrorPropagator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -35,7 +35,6 @@
 				case IProblem.ParsingErrorOnKeyword :
 				case IProblem.ParsingError :
 				case IProblem.ParsingErrorNoSuggestion :
-					break;
 				case IProblem.ParsingErrorInsertTokenBefore :
 				case IProblem.ParsingErrorInsertTokenAfter :
 				case IProblem.ParsingErrorDeleteToken :
@@ -49,6 +48,18 @@
 				case IProblem.ParsingErrorInsertToComplete :
 				case IProblem.ParsingErrorInsertToCompleteScope :
 				case IProblem.ParsingErrorInsertToCompletePhrase :
+				case IProblem.EndOfSource :
+				case IProblem.InvalidHexa :
+				case IProblem.InvalidOctal :
+				case IProblem.InvalidCharacterConstant :
+				case IProblem.InvalidEscape :
+				case IProblem.InvalidInput :
+				case IProblem.InvalidUnicodeEscape :
+				case IProblem.InvalidFloat :
+				case IProblem.NullSourceString :
+				case IProblem.UnterminatedString :
+				case IProblem.UnterminatedComment :
+				case IProblem.InvalidDigit :
 					break;
 				default:
 					continue search;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
index 47c3f3d..1c5ca44 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -92,6 +92,11 @@
  * a second time; in this case, the visits will be nested. In some cases,
  * this can lead to a stack overflow or out of memory condition.</li>
  * </ul>
+ * <p>Note that {@link LineComment} and {@link BlockComment} nodes are
+ * not normally visited in an AST because they are not considered
+ * part of main structure of the AST. Use 
+ * {@link CompilationUnit#getCommentList()} to find these additional
+ * comments nodes.
  * </p>
  * 
  * @see org.eclipse.jdt.core.dom.ASTNode#accept(ASTVisitor)
@@ -168,7 +173,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(AnnotationTypeDeclaration node) {
 		return true;
@@ -186,7 +191,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(AnnotationTypeMemberDeclaration node) {
 		return true;
@@ -327,6 +332,11 @@
 	 * The default implementation does nothing and return true.
 	 * Subclasses may reimplement.
 	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
 	 * 
 	 * @param node the node to visit
 	 * @return <code>true</code> if the children of this node should be
@@ -541,7 +551,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(EnhancedForStatement node) {
 		return true;
@@ -558,7 +568,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(EnumConstantDeclaration node) {
 		return true;
@@ -575,7 +585,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(EnumDeclaration node) {
 		return true;
@@ -770,6 +780,11 @@
 	 * The default implementation does nothing and return true.
 	 * Subclasses may reimplement.
 	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
 	 * 
 	 * @param node the node to visit
 	 * @return <code>true</code> if the children of this node should be
@@ -793,7 +808,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(MarkerAnnotation node) {
 		return true;
@@ -829,7 +844,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(MemberValuePair node) {
 		return true;
@@ -916,7 +931,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(Modifier node) {
 		return true;
@@ -934,7 +949,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(NormalAnnotation node) {
 		return true;
@@ -1000,7 +1015,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(ParameterizedType node) {
 		return true;
@@ -1097,7 +1112,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(QualifiedType node) {
 		return true;
@@ -1163,7 +1178,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(SingleMemberAnnotation node) {
 		return true;
@@ -1442,7 +1457,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(TypeParameter node) {
 		return true;
@@ -1523,7 +1538,7 @@
 	 * @return <code>true</code> if the children of this node should be
 	 * visited, and <code>false</code> if the children of this node should
 	 * be skipped
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(WildcardType node) {
 		return true;
@@ -1536,7 +1551,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(AnnotationTypeDeclaration node) {
 		// default implementation: do nothing
@@ -1549,7 +1564,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(AnnotationTypeMemberDeclaration node) {
 		// default implementation: do nothing
@@ -1656,6 +1671,11 @@
 	 * <p>
 	 * The default implementation does nothing. Subclasses may reimplement.
 	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
 	 * 
 	 * @param node the node to visit
 	 * @since 3.0
@@ -1815,7 +1835,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(EnhancedForStatement node) {
 		// default implementation: do nothing
@@ -1828,7 +1848,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(EnumConstantDeclaration node) {
 		// default implementation: do nothing
@@ -1841,7 +1861,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(EnumDeclaration node) {
 		// default implementation: do nothing
@@ -1984,6 +2004,11 @@
 	 * <p>
 	 * The default implementation does nothing. Subclasses may reimplement.
 	 * </p>
+	 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
+	 * not considered part of main structure of the AST. This method will
+	 * only be called if a client goes out of their way to visit this
+	 * kind of node explicitly.
+	 * </p>
 	 * 
 	 * @param node the node to visit
 	 * @since 3.0
@@ -1999,7 +2024,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(MarkerAnnotation node) {
 		// default implementation: do nothing
@@ -2025,7 +2050,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(MemberValuePair node) {
 		// default implementation: do nothing
@@ -2088,7 +2113,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(Modifier node) {
 		// default implementation: do nothing
@@ -2101,7 +2126,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(NormalAnnotation node) {
 		// default implementation: do nothing
@@ -2150,7 +2175,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(ParameterizedType node) {
 		// default implementation: do nothing
@@ -2223,7 +2248,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(QualifiedType node) {
 		// default implementation: do nothing
@@ -2272,7 +2297,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(SingleMemberAnnotation node) {
 		// default implementation: do nothing
@@ -2479,7 +2504,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(TypeParameter node) {
 		// default implementation: do nothing
@@ -2540,7 +2565,7 @@
 	 * </p>
 	 * 
 	 * @param node the node to visit
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public void endVisit(WildcardType node) {
 		// default implementation: do nothing
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java
index 836ada7..9385faa 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AbstractTypeDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -201,10 +201,8 @@
 	 */
 	public boolean isMemberTypeDeclaration() {
 		ASTNode parent = getParent();
-		// TODO (jeem) - after 3.1 M4 remove mention of EnumConstantDeclaration
 		return (parent instanceof AbstractTypeDeclaration)
-			|| (parent instanceof AnonymousClassDeclaration)
-			|| (parent instanceof EnumConstantDeclaration);
+			|| (parent instanceof AnonymousClassDeclaration);
 	}
 
 	/**
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java
index 35e9577..bcc6ef9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Annotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,13 +20,7 @@
  *		SingleMemberAnnotation
  * </pre>
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
- * @since 3.0
+ * @since 3.1
  */
 public abstract class Annotation extends Expression implements IExtendedModifier {
 	
@@ -43,7 +37,6 @@
 	 * of this node.
 	 * 
 	 * @return the property descriptor
-	 * @since 3.1
 	 */
 	public final ChildPropertyDescriptor getTypeNameProperty() {
 		return internalTypeNameProperty();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java
index 1ebd236..bf6bf0e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -39,14 +39,8 @@
  * modifiers). The source range extends through the last character of the "}"
  * token following the body declarations.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class AnnotationTypeDeclaration extends AbstractTypeDeclaration {
 	
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java
index cf4df07..ed13635 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnnotationTypeMemberDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -33,48 +33,37 @@
  * The source range extends through the last character of the
  * ";" token.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class AnnotationTypeMemberDeclaration extends BodyDeclaration {
 	
 	/**
 	 * The "javadoc" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor JAVADOC_PROPERTY = 
 		internalJavadocPropertyFactory(AnnotationTypeMemberDeclaration.class);
 
 	/**
 	 * The "modifiers" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		internalModifiers2PropertyFactory(AnnotationTypeMemberDeclaration.class);
 	
 	/**
 	 * The "name" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor NAME_PROPERTY = 
 		new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "type" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor TYPE_PROPERTY = 
 		new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "default" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor DEFAULT_PROPERTY = 
 		new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "default", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java
index 0664204..dfc44f3 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AnonymousClassDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java
index 50e7090..80a678d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayAccess.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java
index 5d7c423..1612a2b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayCreation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java
index b59851b..19d837f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java
index 4986a27..a7ed103 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ArrayType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java
index 7cefb96..989b2d0 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AssertStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java
index 93d0339..a1f6365 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Assignment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
index 95f6c24..fbd5b2e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingComparator.java
@@ -1,17 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.core.dom;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
+import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ImportBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
@@ -45,13 +48,9 @@
 			for (int i = 0; i < length; i++) {
 				TypeVariableBinding typeVariableBinding = bindings[i];
 				TypeVariableBinding typeVariableBinding2 = otherBindings[i];
-				if (CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)
-						&& isEqual(typeVariableBinding.declaringElement, typeVariableBinding2.declaringElement, false)
-						&& isEqual(typeVariableBinding.superclass, typeVariableBinding2.superclass, false)
-						&& isEqual(typeVariableBinding.superInterfaces, typeVariableBinding2.superInterfaces, false)) {
-					continue;
+				if (!isEqual(typeVariableBinding, typeVariableBinding2)) {
+					return false;
 				}
-				return false;
 			}
 			return true;
 		}
@@ -112,32 +111,30 @@
 			org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding2,
 			boolean checkTypeVariables) {
 		if (checkTypeVariables) {
-			return (methodBinding == null && methodBinding2 == null)
-				|| (CharOperation.equals(methodBinding.selector, methodBinding2.selector)
-					&& isEqual(methodBinding.returnType, methodBinding2.returnType, false) 
-					&& isEqual(methodBinding.parameters, methodBinding2.parameters, false)
-					&& isEqual(methodBinding.thrownExceptions, methodBinding2.thrownExceptions, false)
-					&& isEqual(methodBinding.typeVariables, methodBinding2.typeVariables, false))
-					&& isEqual(methodBinding.declaringClass, methodBinding2.declaringClass, false);
+			if (!isEqual(methodBinding.typeVariables, methodBinding2.typeVariables, true)
+					|| !isEqual(methodBinding.parameters, methodBinding2.parameters, true)) {
+				return false;
+			}
 		}
 		return (methodBinding == null && methodBinding2 == null)
 			|| (CharOperation.equals(methodBinding.selector, methodBinding2.selector)
-				&& isEqual(methodBinding.returnType, methodBinding2.returnType, false) 
-				&& isEqual(methodBinding.parameters, methodBinding2.parameters, false)
-				&& isEqual(methodBinding.thrownExceptions, methodBinding2.thrownExceptions, false));
+				&& isEqual(methodBinding.returnType, methodBinding2.returnType, checkTypeVariables) 
+				&& isEqual(methodBinding.thrownExceptions, methodBinding2.thrownExceptions, checkTypeVariables)
+				&& isEqual(methodBinding.declaringClass, methodBinding2.declaringClass, true));
 	}
 
 	static boolean isEqual(VariableBinding variableBinding, VariableBinding variableBinding2) {
-		return variableBinding.modifiers == variableBinding2.modifiers
+		return (variableBinding.modifiers & CompilerModifiers.AccJustFlag) == (variableBinding2.modifiers & CompilerModifiers.AccJustFlag)
 				&& CharOperation.equals(variableBinding.name, variableBinding2.name)
-				&& isEqual(variableBinding.type, variableBinding2.type);
+				&& isEqual(variableBinding.type, variableBinding2.type)
+				&& (variableBinding.id == variableBinding2.id);
 	}
 
 	static boolean isEqual(FieldBinding fieldBinding, FieldBinding fieldBinding2) {
-		return fieldBinding.modifiers == fieldBinding2.modifiers
+		return (fieldBinding.modifiers & CompilerModifiers.AccJustFlag) == (fieldBinding2.modifiers & CompilerModifiers.AccJustFlag)
 				&& CharOperation.equals(fieldBinding.name, fieldBinding2.name)
-				&& isEqual(fieldBinding.type, fieldBinding2.type, false)
-				&& isEqual(fieldBinding.declaringClass, fieldBinding2.declaringClass, false);
+				&& isEqual(fieldBinding.type, fieldBinding2.type, true)
+				&& isEqual(fieldBinding.declaringClass, fieldBinding2.declaringClass, true);
 	}
 
 	/**
@@ -172,93 +169,103 @@
 			return true;
 		}
 	}
+	// TODO (olivier) should optimize to use switch(binding.kind()) & modifier bitmask comparisons
 	static boolean isEqual(org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2, boolean checkTypeVariables) {
-		if (typeBinding == null) {
-			return typeBinding2 == null;
-		} else if (typeBinding2 == null) {
+		if (typeBinding == typeBinding2)
+			return true;
+		if (typeBinding == null || typeBinding2 == null)
 			return false;
-		} else if (typeBinding.isBaseType()) {
-			// base type
-			if (!typeBinding2.isBaseType()) {
-				return false;
-			}
-			return typeBinding.id == typeBinding2.id;
-		} else if (typeBinding.isArrayType()) {
-			// array case
-			if (!typeBinding2.isArrayType()) {
-				return false;
-			}
-			return typeBinding.dimensions() == typeBinding2.dimensions()
-					&& isEqual(typeBinding.leafComponentType(), typeBinding2.leafComponentType(), checkTypeVariables);
-		} else {
-			// reference type
-			ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
-			if (!(typeBinding2 instanceof ReferenceBinding)) {
-				return false;
-			}
-			ReferenceBinding referenceBinding2 = (ReferenceBinding) typeBinding2;
-			if (referenceBinding.isParameterizedType()) {
-				if (!referenceBinding2.isParameterizedType()) {
+		
+		switch (typeBinding.kind()) {
+			case Binding.BASE_TYPE :
+				if (!typeBinding2.isBaseType()) {
 					return false;
 				}
-				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) referenceBinding;
-				ParameterizedTypeBinding parameterizedTypeBinding2 = (ParameterizedTypeBinding) referenceBinding2;
+				return typeBinding.id == typeBinding2.id;
+				
+			case Binding.ARRAY_TYPE :
+				if (!typeBinding2.isArrayType()) {
+					return false;
+				}
+				return typeBinding.dimensions() == typeBinding2.dimensions()
+						&& isEqual(typeBinding.leafComponentType(), typeBinding2.leafComponentType(), checkTypeVariables);
+				
+			case Binding.PARAMETERIZED_TYPE :
+				if (!typeBinding2.isParameterizedType()) {
+					return false;
+				}
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) typeBinding;
+				ParameterizedTypeBinding parameterizedTypeBinding2 = (ParameterizedTypeBinding) typeBinding2;
 				if (checkTypeVariables) {
 					if (!isEqual(parameterizedTypeBinding.arguments, parameterizedTypeBinding2.arguments, false)) {
 						return false;
 					}
 				}
-				return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
-					&& (referenceBinding.isInterface() == referenceBinding2.isInterface())
-					&& (referenceBinding.isEnum() == referenceBinding2.isEnum())
-					&& (referenceBinding.isAnnotationType() == referenceBinding2.isAnnotationType())
-					&& (referenceBinding.modifiers == referenceBinding2.modifiers);
-			} else if (referenceBinding.isWildcard()) {
-				if (!referenceBinding2.isWildcard()) {
+				return CharOperation.equals(parameterizedTypeBinding.compoundName, parameterizedTypeBinding2.compoundName)
+					&& (parameterizedTypeBinding.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
+							== (parameterizedTypeBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation));
+							
+			case Binding.WILDCARD_TYPE :
+				if (!typeBinding2.isWildcard()) {
 					return false;
 				}
-				WildcardBinding wildcardBinding = (WildcardBinding) referenceBinding;
-				WildcardBinding wildcardBinding2 = (WildcardBinding) referenceBinding2;
-				return isEqual(wildcardBinding.bound, wildcardBinding2.bound)
-					&& wildcardBinding.kind == wildcardBinding2.kind;
-			} else if (referenceBinding.isGenericType()) {
-				if (!referenceBinding2.isGenericType()) {
+				WildcardBinding wildcardBinding = (WildcardBinding) typeBinding;
+				WildcardBinding wildcardBinding2 = (WildcardBinding) typeBinding2;
+				return isEqual(wildcardBinding.bound, wildcardBinding2.bound, checkTypeVariables)
+					&& wildcardBinding.boundKind == wildcardBinding2.boundKind;
+				
+			case Binding.TYPE_PARAMETER :
+				if (!(typeBinding2.isTypeVariable())) {
 					return false;
 				}
+				if (typeBinding.isCapture()) {
+					if (!(typeBinding2.isCapture())) {
+						return false;
+					}
+					CaptureBinding captureBinding = (CaptureBinding) typeBinding;
+					CaptureBinding captureBinding2 = (CaptureBinding) typeBinding2;
+					return isEqual(captureBinding.wildcard, captureBinding2.wildcard, checkTypeVariables);
+				}
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) typeBinding;
+				TypeVariableBinding typeVariableBinding2 = (TypeVariableBinding) typeBinding2;
 				if (checkTypeVariables) {
-					if (!isEqual(referenceBinding.typeVariables(), referenceBinding2.typeVariables(), false)) {
+					return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)
+						&& isEqual(typeVariableBinding.declaringElement, typeVariableBinding2.declaringElement, false)
+						&& isEqual(typeVariableBinding.superclass(), typeVariableBinding2.superclass(), true)
+						&& isEqual(typeVariableBinding.superInterfaces(), typeVariableBinding2.superInterfaces(), true);
+				} else {
+					return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName);
+				}
+			
+			case Binding.GENERIC_TYPE :
+				if (!typeBinding2.isGenericType()) {
+					return false;
+				}
+				ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
+				ReferenceBinding referenceBinding2 = (ReferenceBinding) typeBinding2;
+				if (checkTypeVariables) {
+					if (!isEqual(referenceBinding.typeVariables(), referenceBinding2.typeVariables(), true)) {
 						return false;
 					}
 				}
 				return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
-					&& (referenceBinding.isGenericType() == referenceBinding2.isGenericType())
-					&& (referenceBinding.isRawType() == referenceBinding2.isRawType())
-					&& (referenceBinding.isInterface() == referenceBinding2.isInterface())
-					&& (referenceBinding.isEnum() == referenceBinding2.isEnum())
-					&& (referenceBinding.isAnnotationType() == referenceBinding2.isAnnotationType())
-					&& (referenceBinding.modifiers == referenceBinding2.modifiers);
-			} else if (referenceBinding instanceof TypeVariableBinding) {
-				if (!(referenceBinding2 instanceof TypeVariableBinding)) {
+					&& (referenceBinding.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
+							== (referenceBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation));
+		
+			case Binding.RAW_TYPE :
+			default :
+				if (!(typeBinding2 instanceof ReferenceBinding)) {
 					return false;
-				}
-				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) referenceBinding;
-				TypeVariableBinding typeVariableBinding2 = (TypeVariableBinding) referenceBinding2;
-				if (checkTypeVariables) {
-					return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)
-						&& isEqual(typeVariableBinding.declaringElement, typeVariableBinding2.declaringElement, false)
-						&& isEqual(typeVariableBinding.superclass, typeVariableBinding2.superclass, false)
-						&& isEqual(typeVariableBinding.superInterfaces, typeVariableBinding2.superInterfaces, false);
-				} else {
-					return CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName);
-				}
-			} else {
+				}				
+				referenceBinding = (ReferenceBinding) typeBinding;
+				referenceBinding2 = (ReferenceBinding) typeBinding2;
 				return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
+					&& CharOperation.equals(referenceBinding.constantPoolName(), referenceBinding2.constantPoolName())
+					&& (!referenceBinding2.isGenericType())
 					&& (referenceBinding.isRawType() == referenceBinding2.isRawType())
-					&& (referenceBinding.isInterface() == referenceBinding2.isInterface())
-					&& (referenceBinding.isEnum() == referenceBinding2.isEnum())
-					&& (referenceBinding.isAnnotationType() == referenceBinding2.isAnnotationType())
-					&& (referenceBinding.modifiers == referenceBinding2.modifiers);
-			}
+					&& (referenceBinding.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation))
+							== (referenceBinding2.modifiers & (CompilerModifiers.AccJustFlag | IConstants.AccInterface | IConstants.AccEnum | IConstants.AccAnnotation));
+				
 		}
 	}
 	/**
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingKey.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingKey.java
deleted file mode 100644
index 525ed53..0000000
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingKey.java
+++ /dev/null
@@ -1,419 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.core.dom;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Wildcard;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
-import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
-import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
-import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
-
-/**
- * Internal class.
- * @since 3.1
- */
-class BindingKey {
-	 char[][] compoundName;
-	 int dimension;
-	 BindingKeyScanner scanner;
-	 CompilationUnitResolver resolver;
-	 LookupEnvironment environment;
-	 
-	 BindingKey(String key, CompilationUnitResolver resolver) {
-	 	this.scanner = new BindingKeyScanner(key.toCharArray());
-	 	this.resolver = resolver;
-	 	this.environment = resolver.lookupEnvironment;
-	 	reset();
-	 }
-	 
-	 /*
-	  * If not already cached, computes and cache the compound name (pkg name + top level name) of this key.
-	  * Returns the package name if key is a pkg key.
-	  * Returns an empty array if malformed.
-	  * This key's scanner should be positioned on the package or type token.
-	  */
-	 char[][] compoundName() {
-	 	if (this.compoundName == null) {
-	 		switch(this.scanner.nextToken()) {
-	 			case BindingKeyScanner.PACKAGE:
-	 			case BindingKeyScanner.TYPE:
-		 			this.compoundName = CharOperation.splitOn('/', this.scanner.getTokenSource());
-		 			break;
-		 		case BindingKeyScanner.ARRAY:
-		 			this.dimension = this.scanner.getTokenSource().length;
-		 			if (this.scanner.nextToken() == BindingKeyScanner.TYPE)
-			 			this.compoundName = CharOperation.splitOn('/', this.scanner.getTokenSource());
-		 			else
-		 				// malformed key
-				 		this.compoundName = CharOperation.NO_CHAR_CHAR;
-		 			break;
-		 		default:
-			 		// malformed key
-			 		this.compoundName = CharOperation.NO_CHAR_CHAR;
-		 			break;
-	 		}
-	 	}
-	 	return this.compoundName;
-	 }
-	 
-	 /*
-	  * If the given dimension is greater than 0 returns an array binding for the given type binding.
-	  * Otherwise return the given type binding.
-	  * Returns null if the given type binding is null.
-	  */
-	 Binding getArrayBinding(int dim, TypeBinding binding) {
-	 	if (binding == null) return null;
-	 	if (dim == 0) return binding;
-		return this.environment.createArrayType(binding, dim);
-	}
-	
-	TypeBinding getBaseTypeBinding(char[] signature) {
-		switch (signature[0]) {
-			case 'I' :
-				return BaseTypes.IntBinding;
-			case 'Z' :
-				return BaseTypes.BooleanBinding;
-			case 'V' :
-				return BaseTypes.VoidBinding;
-			case 'C' :
-				return BaseTypes.CharBinding;
-			case 'D' :
-				return BaseTypes.DoubleBinding;
-			case 'B' :
-				return BaseTypes.ByteBinding;
-			case 'F' :
-				return BaseTypes.FloatBinding;
-			case 'J' :
-				return BaseTypes.LongBinding;
-			case 'S' :
-				return BaseTypes.ShortBinding;
-			default :
-				return null;
-		}
-	}
-	 
-	/*
-	 * Returns a binary binding corresonding to this key's compound name.
-	 * Returns null if not found.
-	 * This key's scanner should be positioned on the token after the top level type.
-	 */
-	Binding getBinaryBinding() {
-		TypeBinding binding = this.environment.getType(this.compoundName);
-		return getArrayBinding(this.dimension, binding);
-	}
-	 
-	 /*
-	  * Finds the compilation unit declaration corresponding to the key in the given lookup environment.
-	  * Returns null if no compilation unit declaration could be found.
-	  * This key's scanner should be positioned on the package token.
-	  */
-	 CompilationUnitDeclaration getCompilationUnitDeclaration() {
-		char[][] name = compoundName();
-		if (name.length == 0) return null;
-		ReferenceBinding binding = this.environment.getType(name);
-		if (!(binding instanceof SourceTypeBinding)) return null;
-		return ((SourceTypeBinding) binding).scope.compilationUnitScope().referenceContext;
-	 }
-	 
-	 /*
-	  * Returns the compiler binding corresponding to this key.
-	  * This key's scanner should be positioned on the top level type token.
-	  * Returns null otherwise.
-	  */
-	 Binding getCompilerBinding(CompilationUnitDeclaration parsedUnit) {
-	 	switch (this.scanner.token) {
-	 		case BindingKeyScanner.PACKAGE:
-	 			return new PackageBinding(this.compoundName, null, this.environment);
-	 		case BindingKeyScanner.TYPE:
-	 			if (this.compoundName.length == 1 && this.compoundName[0].length == 1) {
-	 				// case of base type
-		 			TypeBinding baseTypeBinding = getBaseTypeBinding(this.compoundName[0]);
-		 			if (baseTypeBinding != null) 
-	 					return getArrayBinding(this.dimension, baseTypeBinding);
-	 			}
-	 			if (parsedUnit == null) 
-	 				return getBinaryBinding();
-	 			char[] typeName = this.compoundName[this.compoundName.length-1];
-	 			int dim = this.dimension;
-	 			TypeBinding binding = getTypeBinding(parsedUnit, parsedUnit.types, typeName);
-	 			if (binding == null) return null;
- 				TypeBinding typeBinding = null;
- 				if (this.scanner.isAtParametersStart()) {
-					if (this.scanner.isAtTypeParameterStart())	 					
-	 					// generic type binding
-	 					typeBinding = getGenericTypeBinding((SourceTypeBinding) binding);
-	 				else if (this.scanner.isAtTypeStart() || this.scanner.isAtWildCardStart())
- 						// parameterized type binding
-	 					typeBinding = getParameterizedTypeBinding((ReferenceBinding) binding, null/*no enclosing type*/); 
- 				} else if (binding.typeVariables().length > 0)
- 					// raw type binding
- 					typeBinding = this.environment.createRawType((ReferenceBinding) binding, null/*no enclosing type*/);
- 				else
-					// non-generic type binding
-					typeBinding = binding;
-	 			if (this.scanner.isAtFieldOrMethodStart()) {
-	 				switch (this.scanner.nextToken()) {
-		 				case BindingKeyScanner.FIELD:
-		 					return getFieldBinding(((ReferenceBinding) typeBinding).fields());
-		 				case BindingKeyScanner.METHOD:
-		 					MethodBinding methodBinding = getMethodBinding(((ReferenceBinding) typeBinding).methods());
-		 					if (this.scanner.isAtParametersStart())
-		 						// parameterized generic method binding
-		 						methodBinding = getParameterizedGenericMethodBinding(methodBinding);
-		 					if (this.scanner.isAtLocalVariableStart()) {
-		 						MethodScope methodScope = methodBinding.sourceMethod().scope;
-		 						return getLocalVariableBinding(methodScope);
-		 					} else
-		 						return methodBinding;
-	 				}
-	 				return null; // malformed key
-	 			} else {
-	 				return getArrayBinding(dim, typeBinding);
-	 			}
-	 	}
-	 	return null;
-	 }
-	 
-	 /*
-	  * Returns the compiler binding corresponding to this key.
-	  * Returns null is malformed.
-	  * This key's scanner should be positioned on the package token.
-	  */
-	 Binding getCompilerBinding() {
-		CompilationUnitDeclaration parsedUnit = getCompilationUnitDeclaration();
-		if (parsedUnit != null) {
-			char[] fileName = parsedUnit.compilationResult.getFileName();
-			// don't resolve a second time the same unit (this would create the same bindingd twice)
-			if (!this.resolver.requestedKeys.containsKey(fileName) && !this.resolver.requestedSources.containsKey(fileName))
-				this.resolver.process(parsedUnit, this.resolver.totalUnits+1);
-		}
-		return getCompilerBinding(parsedUnit);
-	 }
-
-	/*
-	 * Finds the field binding that corresponds to this key in the given field bindings.
-	 * Returns null if not found.
-	 * This key's scanner should be positioned on the field name.
-	 */
-	FieldBinding getFieldBinding(FieldBinding[] fields) {
-	 	if (fields == null) return null;
-	 	char[] fieldName = this.scanner.getTokenSource();
-	 	for (int i = 0, length = fields.length; i < length; i++) {
-			FieldBinding field = fields[i];
-			if (CharOperation.equals(fieldName, field.name)) 
-				return field;
-		}
-	 	return null;
-	 }
-	 
-	 /*
-	  * Ensures that the given generic type binding corresponds to this key.
-	  * This key's scanner should be positionned on the first type parameter name token.
-	  */
-	 SourceTypeBinding getGenericTypeBinding(SourceTypeBinding typeBinding) {
-	 	TypeVariableBinding[] typeVariableBindings = typeBinding.typeVariables();
-	 	for (int i = 0, length = typeVariableBindings.length; i < length; i++) {
-			TypeVariableBinding typeVariableBinding = typeVariableBindings[i];
-			if (this.scanner.nextToken() != BindingKeyScanner.TYPE)
-				return null;
-		 	char[] typeVariableName = this.scanner.getTokenSource();
-			if (!CharOperation.equals(typeVariableName, typeVariableBinding.sourceName()))
-				return null;
-		}
-	 	return typeBinding;
-	 }
-	 
-	 /*
-	  * Returns the string that this binding key wraps.
-	  */
-	 String getKey() {
-	 	return new String(this.scanner.source);
-	 }
-	 
-	 LocalVariableBinding getLocalVariableBinding(BlockScope scope) {
-	 	if (this.scanner.nextToken() != BindingKeyScanner.LOCAL_VAR)
-			return null; // malformed key
-		char[] varName = this.scanner.getTokenSource();
-		if (Character.isDigit(varName[0])) {
-			int index = Integer.parseInt(new String(varName));
-			if (index >= scope.subscopeCount)
-				return null; // malformed key
-			if (!this.scanner.isAtLocalVariableStart())
-				return null; // malformed key
-			return getLocalVariableBinding((BlockScope) scope.subscopes[index]);
-		} else {
-		 	for (int i = 0; i < scope.localIndex; i++) {
-				LocalVariableBinding local = scope.locals[i];
-				if (CharOperation.equals(varName, local.name))
-					return local;
-			}
-		}
-	 	return null;
-	 }
-	 
-	/*
-	 * Finds the method binding that corresponds to this key in the given method bindings.
-	 * Returns null if not found.
-	 * This key's scanner should be positioned on the selector token.
-	 */
-	 MethodBinding getMethodBinding(MethodBinding[] methods) {
-	 	if (methods == null) return null;
-	 	char[] selector = this.scanner.getTokenSource();
-	 	this.scanner.skipMethodSignature();
-	 	char[] signature = this.scanner.getTokenSource();
-	 	
-	 	nextMethod: for (int i = 0, methodLength = methods.length; i < methodLength; i++) {
-			MethodBinding method = methods[i];
-			if (CharOperation.equals(selector, method.selector) || (selector.length == 0 && method.isConstructor())) {
-				if (CharOperation.equals(signature, method.genericSignature()))
-					return method;
-				return method;
-			}
-		}
-	 	return null;
-	 }
-	 
-	 
-	 /*
-	  * Finds parameterized generic method binding that corresponds to this key.
-	  * This key's scanner should be positionned on the first type argument name token.
-	  */
-	 ParameterizedGenericMethodBinding getParameterizedGenericMethodBinding(MethodBinding methodBinding) {
-	 	int length = methodBinding.typeVariables().length;
-	 	TypeBinding[] arguments = new TypeBinding[length];
-	 	for (int i = 0; i < length; i++) {
-			reset();
-			Binding argument = getCompilerBinding();
-			if (argument == null) 
-				return null;
-			arguments[i] = (TypeBinding) argument;
-		}
-	 	return new ParameterizedGenericMethodBinding(methodBinding, arguments, this.environment);
-	 }
-	 
-	 /*
-	  * Finds parameterized type binding that corresponds to this key.
-	  * This key's scanner should be positionned on the first type argument name token.
-	  */
-	 ParameterizedTypeBinding getParameterizedTypeBinding(ReferenceBinding genericType, ReferenceBinding enclosingType) {
-	 	TypeVariableBinding[] typeVariableBindings = genericType.typeVariables();
-	 	int length = typeVariableBindings.length;
-	 	TypeBinding[] arguments = new TypeBinding[length];
-	 	for (int i = 0; i < length; i++) {
-	 		TypeBinding argument;
-	 		if (this.scanner.isAtWildCardStart()) {
-	 			argument = getWildCardBinding(genericType, i);
-	 		} else {
-				reset();
-				argument = (TypeBinding) getCompilerBinding();
-	 		}
-			if (argument == null) 
-				return this.environment.createRawType(genericType, enclosingType);
-			arguments[i] =argument;
-	 		
-		}
-	 	ParameterizedTypeBinding parameterizedTypeBinding = this.environment.createParameterizedType(genericType, arguments, enclosingType);
-	 	// skip ";>"
-	 	this.scanner.skipParametersEnd();
-	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == BindingKeyScanner.TYPE) {
-	 		char[] typeName = this.scanner.getTokenSource();
-	 		ReferenceBinding memberType = genericType.getMemberType(typeName);
-	 		return getParameterizedTypeBinding(memberType, parameterizedTypeBinding);
-	 	} else {
-		 	return parameterizedTypeBinding;
-	 	}
-	 }
-	 
-	/*
-	 * Finds the type binding that corresponds to this key in the given type bindings.
-	 * Returns null if not found.
-	 * This key's scanner should be positioned on the type name token.
-	 */
-	 TypeBinding getTypeBinding(CompilationUnitDeclaration parsedUnit, TypeDeclaration[] types, char[] typeName) {
-	 	if (Character.isDigit(typeName[0])) {
-	 		// anonymous or local type
-	 		int nextToken = BindingKeyScanner.TYPE;
-	 		while (this.scanner.isAtMemberTypeStart()) 
-	 			nextToken = this.scanner.nextToken();
-	 		typeName = nextToken == BindingKeyScanner.END ? this.scanner.source : CharOperation.subarray(this.scanner.source, 0, this.scanner.index+1);
-	 		LocalTypeBinding[] localTypeBindings  = parsedUnit.localTypes;
-	 		for (int i = 0; i < parsedUnit.localTypeCount; i++)
-	 			if (CharOperation.equals(typeName, localTypeBindings[i].signature()))
-	 				return localTypeBindings[i];
-	 		return null;
-	 	} else {
-	 		// member type
-		 	if (types == null) return null;
-			for (int i = 0, length = types.length; i < length; i++) {
-				TypeDeclaration declaration = types[i];
-				if (CharOperation.equals(typeName, declaration.name)) {
-					if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == BindingKeyScanner.TYPE)
-						return getTypeBinding(parsedUnit, declaration.memberTypes, this.scanner.getTokenSource());
-					else
-						return declaration.binding;
-				}
-			}
-	 	}
-		return null;
-	 }
-	 
-	 TypeBinding getWildCardBinding(ReferenceBinding genericType, int rank) {
-	 	if (this.scanner.nextToken() != BindingKeyScanner.TYPE) return null;
-	 	char[] source = this.scanner.getTokenSource();
-	 	if (source.length == 0) return null; //malformed key
-	 	int kind = -1;
-	 	TypeBinding bound = null;
-	 	switch (source[0]) {
-		 	case '*':
-		 		kind = Wildcard.UNBOUND;
-		 		break;
-		 	case '+':
-		 		reset();
-		 		kind = Wildcard.EXTENDS;
-		 		bound = (TypeBinding) getCompilerBinding();
-		 		break;
-		 	case '-':
-		 		reset();
-		 		kind = Wildcard.SUPER;
-		 		bound = (TypeBinding) getCompilerBinding();
-		 		break;
-	 	}
-	 	if (kind == -1) return null; // malformed key
- 		return this.environment.createWildcard(genericType, rank, bound, kind);
-	 }
-	 
-	 /*
-	  * Forget about this key's compound name and dimension.
-	  */
-	 void reset() {
-	 	this.compoundName = null;
-	 	this.dimension = 0;
-	 }
-	 
-	 public String toString() {
-		return getKey();
-	}
-}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingKeyScanner.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingKeyScanner.java
deleted file mode 100644
index 9f45b2a..0000000
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingKeyScanner.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.core.dom;
-
-import org.eclipse.jdt.core.compiler.CharOperation;
-
-/**
- * Internal class.
- * @since 3.1
- */
-class BindingKeyScanner {
-	
-	static final int START = -1;
-	static final int PACKAGE = 0;
-	static final int TYPE = 1;
-	static final int FIELD = 2;
-	static final int METHOD = 3;
-	static final int ARRAY = 4;
-	static final int TYPE_PARAMETER = 5;
-	static final int LOCAL_VAR = 6;
-	static final int END = 7;
-	
-	int index = 0, start;
-	char[] source;
-	int token = START;
-
-	BindingKeyScanner(char[] source) {
-		this.source = source;
-	}
-	
-	char[] getTokenSource() {
-		int length = this.index-this.start;
-		char[] result = new char[length];
-		System.arraycopy(this.source, this.start, result, 0, length);
-		return result;
-	}
-	
-	boolean isAtFieldOrMethodStart() {
-		return 
-			this.index+1 < this.source.length
-			&& this.source[this.index+1] == '.';
-	}
-	
-	boolean isAtLocalVariableStart() {
-		return 
-			this.index < this.source.length
-			&& this.source[this.index] == '#';
-	}
-	
-	boolean isAtMemberTypeStart() {
-		return 
-			this.index < this.source.length
-			&& (this.source[this.index] == '$'
-				|| (this.source[this.index] == '.' && this.source[this.index-1] == '>'));
-	}
-	
-	boolean isAtParametersStart() {
-		char currentChar;
-		return 
-			this.index > 0
-			&& this.index < this.source.length
-			&& ((currentChar = this.source[this.index]) == '<'
-				|| currentChar == '%');
-	}
-	
-	boolean isAtTypeParameterStart() {
-		return 
-			this.index+1 < this.source.length
-			&& this.source[this.index+1] == 'T';
-	}
-	
-	boolean isAtTypeStart() {
-		return this.index+1 < this.source.length && "LIZVCDBFJS[".indexOf(this.source[this.index+1]) != -1; //$NON-NLS-1$
-	}
-	
-	boolean isAtWildCardStart() {
-		return this.index+1 < this.source.length && "*+-".indexOf(this.source[this.index+1]) != -1; //$NON-NLS-1$
-	}
-	
-	int nextToken() {
-		int previousTokenEnd = this.index;
-		this.start = this.index;
-		int length = this.source.length;
-		while (this.index <= length) {
-			char currentChar = this.index == length ? Character.MIN_VALUE : this.source[this.index];
-			switch (currentChar) {
-				case 'B':
-				case 'C':
-				case 'D':
-				case 'F':
-				case 'I':
-				case 'J':
-				case 'S':
-				case 'V':
-				case 'Z':
-					// base type
-					if (this.index == previousTokenEnd) {
-						this.index++;
-						this.token = TYPE;
-						return this.token;
-					}
-					break;
-				case 'L':
-				case 'T':
-					if (this.index == previousTokenEnd) {
-						this.start = this.index+1;
-					}
-					break;
-				case ';':
-				case '$':
-					if (this.index == previousTokenEnd) {
-						this.start = this.index+1;
-						previousTokenEnd = this.start;
-					} else {
-						this.token = TYPE;
-						return this.token;
-					}
-					break;
-				case '.':
-				case '%':
-					this.start = this.index+1;
-					previousTokenEnd = this.start;
-					break;
-				case '[':
-					while (this.index < length && this.source[this.index] == '[')
-						this.index++;
-					this.token = ARRAY;
-					return this.token;
-				case '<':
-					if (this.index == previousTokenEnd) {
-						this.start = this.index+1;
-						previousTokenEnd = this.start;
-					} else if (this.start > 0) {
-						switch (this.source[this.start-1]) {
-							case '.':
-								if (this.source[this.start-2] == '>')
-									// case of member type where enclosing type is parameterized
-									this.token = TYPE;
-								else
-									this.token = METHOD;
-								return this.token;
-							default:
-								this.token = TYPE;
-								return this.token;
-						}
-					} 
-					break;
-				case '(':
-					this.token = METHOD;
-					return this.token;
-				case ')':
-					this.start = ++this.index;
-					this.token = END;
-					return this.token;
-				case ':':
-					this.token = TYPE_PARAMETER;
-					return this.token;
-				case '#':
-					if (this.index == previousTokenEnd) {
-						this.start = this.index+1;
-						previousTokenEnd = this.start;
-					} else {
-						this.token = LOCAL_VAR;
-						return this.token;
-					}
-					break;
-				case Character.MIN_VALUE:
-					switch (this.token) {
-						case START:
-							this.token = PACKAGE;
-							break;
-						case METHOD:
-						case LOCAL_VAR:
-							this.token = LOCAL_VAR;
-							break;
-						case TYPE:
-							if (this.index > this.start && this.source[this.start-1] == '.')
-								this.token = FIELD;
-							else
-								this.token = END;
-							break;
-						default:
-							this.token = END;
-							break;
-					}
-					return this.token;
-				case '*':
-				case '+':
-				case '-':
-					this.index++;
-					this.token = TYPE;
-					return this.token;
-			}
-			this.index++;
-		}
-		this.token = END;
-		return this.token;
-	}
-	
-	void skipMethodSignature() {
-		char currentChar;
-		while (this.index < this.source.length && (currentChar = this.source[this.index]) != '#' && currentChar != '%')
-			this.index++;
-	}
-	
-	void skipParametersEnd() {
-		while (this.index < this.source.length && this.source[this.index] != '>')
-			this.index++;
-		this.index++;
-	}
-	
-	public String toString() {
-		StringBuffer buffer = new StringBuffer();
-		switch (this.token) {
-			case START:
-				buffer.append("START: "); //$NON-NLS-1$
-				break;
-			case PACKAGE:
-				buffer.append("PACKAGE: "); //$NON-NLS-1$
-				break;
-			case TYPE:
-				buffer.append("TYPE: "); //$NON-NLS-1$
-				break;
-			case FIELD:
-				buffer.append("FIELD: "); //$NON-NLS-1$
-				break;
-			case METHOD:
-				buffer.append("METHOD: "); //$NON-NLS-1$
-				break;
-			case ARRAY:
-				buffer.append("ARRAY: "); //$NON-NLS-1$
-				break;
-			case TYPE_PARAMETER:
-				buffer.append("TYPE PARAMETER: "); //$NON-NLS-1$
-				break;
-			case LOCAL_VAR:
-				buffer.append("LOCAL VAR: "); //$NON-NLS-1$
-				break;
-			case END:
-				buffer.append("END: "); //$NON-NLS-1$
-				break;
-		}
-		if (this.index < 0) {
-			buffer.append("**"); //$NON-NLS-1$
-			buffer.append(this.source);
-		} else if (this.index <= this.source.length) {
-			buffer.append(CharOperation.subarray(this.source, 0, this.start));
-			buffer.append('*');
-			if (this.start <= this.index) {
-				buffer.append(CharOperation.subarray(this.source, this.start, this.index));
-				buffer.append('*');
-				buffer.append(CharOperation.subarray(this.source, this.index, this.source.length));
-			} else {
-				buffer.append('*');
-				buffer.append(CharOperation.subarray(this.source, this.start, this.source.length));
-			}
-		} else {
-			buffer.append(this.source);
-			buffer.append("**"); //$NON-NLS-1$
-		}
-		return buffer.toString();
-	}
-}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
index 834c356..2c8db33 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -35,547 +35,6 @@
 	}
 
 	/**
-	 * Allows the user to store information about the given old/new pair of
-	 * AST nodes.
-	 * <p>
-	 * The default implementation of this method does nothing.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param newNode the new AST node
-	 * @param oldASTNode the old AST node
-	 */
-	void store(ASTNode newNode, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
-		// default implementation: do nothing
-	}
-
-	/**
-	 * Resolves the given name and returns the type binding for it.
-	 * <p>
-	 * The implementation of <code>Name.resolveBinding</code> forwards to
-	 * this method. How the name resolves is often a function of the context
-	 * in which the name node is embedded as well as the name itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param name the name of interest
-	 * @return the binding for the name, or <code>null</code> if no binding is
-	 *    available
-	 */
-	IBinding resolveName(Name name) {
-		return null;
-	}
-
-	/**
-	 * Resolves the given type and returns the type binding for it.
-	 * <p>
-	 * The implementation of <code>Type.resolveBinding</code>
-	 * forwards to this method. How the type resolves is often a function
-	 * of the context in which the type node is embedded as well as the type
-	 * subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param type the type of interest
-	 * @return the binding for the given type, or <code>null</code>
-	 *    if no binding is available 
-	 */
-	ITypeBinding resolveType(Type type) {
-		return null;
-	}
-
-	/**
-	 * Resolves the given well known type by name and returns the type binding
-	 * for it.
-	 * <p>
-	 * The implementation of <code>AST.resolveWellKnownType</code>
-	 * forwards to this method.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param name the name of a well known type
-	 * @return the corresponding type binding, or <code>null<code> if the 
-	 *   named type is not considered well known or if no binding can be found
-	 *   for it
-	 */
-	ITypeBinding resolveWellKnownType(String name) {
-		return null;
-	}
-
-	/**
-	 * Returns the compilation unit scope used by this binding resolver.
-	 * Returns <code>null</code> if none.
-	 * 
-	 * @return the compilation unit scope by this resolver, or <code>null</code> if none.
-	 */
-	public CompilationUnitScope scope() {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given class or interface declaration and returns the binding
-	 * for it.
-	 * <p>
-	 * The implementation of <code>TypeDeclaration.resolveBinding</code> 
-	 * (and <code>TypeDeclarationStatement.resolveBinding</code>) forwards
-	 * to this method. How the type declaration resolves is often a function of
-	 * the context in which the type declaration node is embedded as well as the
-	 * type declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param type the class or interface declaration of interest
-	 * @return the binding for the given type declaration, or <code>null</code>
-	 *    if no binding is available
-	 */
-	ITypeBinding resolveType(TypeDeclaration type) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given type parameter and returns the type binding for the
-	 * type parameter.
-	 * <p>
-	 * The implementation of <code>TypeParameter.resolveBinding</code> 
-	 * forwards to this method. How the declaration resolves is often a 
-	 * function of the context in which the declaration node is embedded as well
-	 * as the declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param typeParameter the type paramter of interest
-	 * @return the binding for the given type parameter, or <code>null</code>
-	 *    if no binding is available
-	 * @since 3.1
-	 */
-	ITypeBinding resolveTypeParameter(TypeParameter typeParameter) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given enum declaration and returns the binding
-	 * for it.
-	 * <p>
-	 * The implementation of <code>EnumDeclaration.resolveBinding</code> 
-	 * forwards to this method. How the enum declaration resolves is often
-	 * a function of the context in which the declaration node is embedded
-	 * as well as the enum declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param type the enum declaration of interest
-	 * @return the binding for the given enum declaration, or <code>null</code>
-	 *    if no binding is available
-	 * @since 3.0
-	 */
-	ITypeBinding resolveType(EnumDeclaration type) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given anonymous class declaration and returns the binding
-	 * for it.
-	 * <p>
-	 * The implementation of <code>AnonymousClassDeclaration.resolveBinding</code> 
-	 * forwards to this method. How the declaration resolves is often a 
-	 * function of the context in which the declaration node is embedded as well
-	 * as the declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param type the anonymous class declaration of interest
-	 * @return the binding for the given class declaration, or <code>null</code>
-	 *    if no binding is available
-	 */
-	ITypeBinding resolveType(AnonymousClassDeclaration type) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given annotation type declaration and returns the binding
-	 * for it.
-	 * <p>
-	 * The implementation of <code>AnnotationTypeDeclaration.resolveBinding</code> 
-	 * forwards to this method. How the declaration resolves is often a 
-	 * function of the context in which the declaration node is embedded as well
-	 * as the declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param type the annotation type declaration of interest
-	 * @return the binding for the given annotation type declaration, or <code>null</code>
-	 *    if no binding is available
-	 * @since 3.0
-	 */
-	ITypeBinding resolveType(AnnotationTypeDeclaration type) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given method declaration and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>MethodDeclaration.resolveBinding</code>
-	 * forwards to this method. How the method resolves is often a function of
-	 * the context in which the method declaration node is embedded as well as
-	 * the method declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param method the method or constructor declaration of interest
-	 * @return the binding for the given method declaration, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IMethodBinding resolveMethod(MethodDeclaration method) {
-		return null;
-	}
-	/**
-	 * Resolves the given method invocation and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>MethodInvocation.resolveMethodBinding</code>
-	 * forwards to this method. How the method resolves is often a function of
-	 * the context in which the method invocation node is embedded as well as
-	 * the method invocation subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param method the method invocation of interest
-	 * @return the binding for the given method invocation, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IMethodBinding resolveMethod(MethodInvocation method) {
-		return null;
-	}
-	/**
-	 * Resolves the given method invocation and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>MethodInvocation.resolveMethodBinding</code>
-	 * forwards to this method. How the method resolves is often a function of
-	 * the context in which the method invocation node is embedded as well as
-	 * the method invocation subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param method the method invocation of interest
-	 * @return the binding for the given method invocation, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IMethodBinding resolveMethod(SuperMethodInvocation method) {
-		return null;
-	}	
-	/**
-	 * Resolves the given variable declaration and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>VariableDeclaration.resolveBinding</code>
-	 * forwards to this method. How the variable declaration resolves is often
-	 * a function of the context in which the variable declaration node is 
-	 * embedded as well as the variable declaration subtree itself. VariableDeclaration 
-	 * declarations used as local variable, formal parameter and exception 
-	 * variables resolve to local variable bindings; variable declarations
-	 * used to declare fields resolve to field bindings.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param variable the variable declaration of interest
-	 * @return the binding for the given variable declaration, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IVariableBinding resolveVariable(VariableDeclaration variable) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given enum constant declaration and returns the binding for
-	 * the field.
-	 * <p>
-	 * The implementation of <code>EnumConstantDeclaration.resolveVariable</code>
-	 * forwards to this method.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param enumConstant the enum constant declaration of interest
-	 * @return the field binding for the given enum constant declaration, or 
-	 *    <code>null</code> if no binding is available
-	 * @since 3.0
-	 */
-	IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
-		return null;
-	}
-		
-	/**
-	 * Resolves the given annotation type declaration and returns the binding
-	 * for it.
-	 * <p>
-	 * The implementation of <code>AnnotationTypeMemberDeclaration.resolveBinding</code> 
-	 * forwards to this method. How the declaration resolves is often a 
-	 * function of the context in which the declaration node is embedded as well
-	 * as the declaration subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param member the annotation type member declaration of interest
-	 * @return the binding for the given annotation type member declaration, or <code>null</code>
-	 *    if no binding is available
-	 * @since 3.0
-	 */
-	IMethodBinding resolveMember(AnnotationTypeMemberDeclaration member) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the type of the given expression and returns the type binding
-	 * for it. 
-	 * <p>
-	 * The implementation of <code>Expression.resolveTypeBinding</code>
-	 * forwards to this method. The result is often a function of the context
-	 * in which the expression node is embedded as well as the expression 
-	 * subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param expression the expression whose type is of interest
-	 * @return the binding for the type of the given expression, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	ITypeBinding resolveExpressionType(Expression expression) {
-		return null;
-	}
-
-	/**
-	 * Resolves the given field access and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>FieldAccess.resolveFieldBinding</code>
-	 * forwards to this method. How the field resolves is often a function of
-	 * the context in which the field access node is embedded as well as
-	 * the field access subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param fieldAccess the field access of interest
-	 * @return the binding for the given field access, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IVariableBinding resolveField(FieldAccess fieldAccess) {
-		return null;
-	}
-		
-	/**
-	 * Resolves the given super field access and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>SuperFieldAccess.resolveFieldBinding</code>
-	 * forwards to this method. How the field resolves is often a function of
-	 * the context in which the super field access node is embedded as well as
-	 * the super field access subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param fieldAccess the super field access of interest
-	 * @return the binding for the given field access, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IVariableBinding resolveField(SuperFieldAccess fieldAccess) {
-		return null;
-	}
-
-	/**
-	 * Resolves the given import declaration and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>ImportDeclaration.resolveBinding</code>
-	 * forwards to this method.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param importDeclaration the import declaration of interest
-	 * @return the binding for the given package declaration, or 
-	 *         the package binding (for on-demand imports) or type binding
-	 *         (for single-type imports), or <code>null</code> if no binding is
-	 *         available
-	 */
-	IBinding resolveImport(ImportDeclaration importDeclaration) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given package declaration and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>PackageDeclaration.resolveBinding</code>
-	 * forwards to this method.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param pkg the package declaration of interest
-	 * @return the binding for the given package declaration, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IPackageBinding resolvePackage(PackageDeclaration pkg) {
-		return null;
-	}
-	
-	/**
-	 * Resolves and returns the binding for the constructor being invoked.
-	 * <p>
-	 * The implementation of
-	 * <code>ConstructorInvocation.resolveConstructor</code>
-	 * forwards to this method. Which constructor is invoked is often a function
-	 * of the context in which the expression node is embedded as well as
-	 * the expression subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param expression the expression of interest
-	 * @return the binding for the constructor being invoked, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IMethodBinding resolveConstructor(ConstructorInvocation expression) {
-		return null;
-	}
-	
-	/**
-	 * Resolves and returns the binding for the constructor being invoked.
-	 * <p>
-	 * The implementation of
-	 * <code>SuperConstructorInvocation.resolveConstructor</code>
-	 * forwards to this method. Which constructor is invoked is often a function
-	 * of the context in which the expression node is embedded as well as
-	 * the expression subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param expression the expression of interest
-	 * @return the binding for the constructor being invoked, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IMethodBinding resolveConstructor(SuperConstructorInvocation expression) {
-		return null;
-	}
-	
-	/**
-	 * Resolves and returns the binding for the constructor being invoked.
-	 * <p>
-	 * The implementation of
-	 * <code>ClassInstanceCreation.resolveConstructor</code>
-	 * forwards to this method. Which constructor is invoked is often a function
-	 * of the context in which the expression node is embedded as well as
-	 * the expression subtree itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param expression the expression of interest
-	 * @return the binding for the constructor being invoked, or 
-	 *    <code>null</code> if no binding is available
-	 */
-	IMethodBinding resolveConstructor(ClassInstanceCreation expression) {
-		return null;
-	}
-	
-	/**
-	 * Resolves the given reference and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>MemberRef.resolveBinding</code> forwards to
-	 * this method. How the name resolves is often a function of the context
-	 * in which the name node is embedded as well as the name itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param ref the reference of interest
-	 * @return the binding for the reference, or <code>null</code> if no binding is
-	 *    available
-	 * @since 3.0
-	 */
-	IBinding resolveReference(MemberRef ref) {
-		return null;
-	}
-
-	/**
-	 * Resolves the given reference and returns the binding for it.
-	 * <p>
-	 * The implementation of <code>MethodRef.resolveBinding</code> forwards to
-	 * this method. How the name resolves is often a function of the context
-	 * in which the name node is embedded as well as the name itself.
-	 * </p>
-	 * <p>
-	 * The default implementation of this method returns <code>null</code>.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * 
-	 * @param ref the reference of interest
-	 * @return the binding for the reference, or <code>null</code> if no binding is
-	 *    available
-	 * @since 3.0
-	 */
-	IBinding resolveReference(MethodRef ref) {
-		return null;
-	}
-
-	/**
 	 * Finds the corresponding AST node from which the given binding originated.
 	 * Returns <code>null</code> if the binding does not correspond to any node
 	 * in the compilation unit.
@@ -632,18 +91,33 @@
 	ASTNode findDeclaringNode(String bindingKey) {
 		return null;
 	}
-	
+
 	/**
-	 * Returns the new type binding corresponding to the given old type binding.
+	 * Allows the user to get information about the given old/new pair of
+	 * AST nodes.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param currentNode the new node
+	 * @return org.eclipse.jdt.internal.compiler.ast.ASTNode
+	 */
+	org.eclipse.jdt.internal.compiler.ast.ASTNode getCorrespondingNode(ASTNode currentNode) {
+		return null;
+	}
+
+	/**
+	 * Returns the new method binding corresponding to the given old method binding.
 	 * <p>
 	 * The default implementation of this method returns <code>null</code>.
 	 * Subclasses may reimplement.
 	 * </p>
 	 * 
-	 * @param referenceBinding the old type binding
-	 * @return the new type binding
+	 * @param methodBinding the old method binding
+	 * @return the new method binding
 	 */
-	ITypeBinding getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) {
+	IMethodBinding getMethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) {
 		return null;
 	}
 
@@ -659,19 +133,19 @@
 	 */
 	IPackageBinding getPackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding) {
 		return null;
-	}		
-
+	}
+	
 	/**
-	 * Returns the new method binding corresponding to the given old method binding.
+	 * Returns the new type binding corresponding to the given old type binding.
 	 * <p>
 	 * The default implementation of this method returns <code>null</code>.
 	 * Subclasses may reimplement.
 	 * </p>
 	 * 
-	 * @param methodBinding the old method binding
-	 * @return the new method binding
+	 * @param referenceBinding the old type binding
+	 * @return the new type binding
 	 */
-	IMethodBinding getMethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) {
+	ITypeBinding getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) {
 		return null;
 	}
 	
@@ -700,6 +174,642 @@
 	}
 	
 	/**
+	 * This method is used to record the scope and its corresponding node.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * @param astNode
+	 */	
+	void recordScope(ASTNode astNode, BlockScope blockScope) {
+		// default implementation: do nothing
+	}
+	
+	/**
+	 * Returns whether this expression node is the site of a boxing
+	 * conversion (JLS3 5.1.7). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 * 
+	 * @return <code>true</code> if this expression is the site of a
+	 * boxing conversion, or <code>false</code> if either no boxing conversion
+	 * is involved or if bindings were not requested when the AST was created
+	 * @since 3.1
+	 */
+	boolean resolveBoxing(Expression expression) {
+		return false;
+	}
+	
+	/**
+	 * Returns whether this expression node is the site of an unboxing
+	 * conversion (JLS3 5.1.8). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 * 
+	 * @return <code>true</code> if this expression is the site of an
+	 * unboxing conversion, or <code>false</code> if either no unboxing
+	 * conversion is involved or if bindings were not requested when the
+	 * AST was created
+	 * @since 3.1
+	 */
+	boolean resolveUnboxing(Expression expression) {
+		return false;
+	}
+
+	/**
+	 * Resolves and returns the compile-time constant expression value as 
+	 * specified in JLS2 15.28, if this expression has one. Constant expression
+	 * values are unavailable unless bindings are requested when the AST is
+	 * being built. If the type of the value is a primitive type, the result
+	 * is the boxed equivalent (i.e., int returned as an <code>Integer</code>);
+	 * if the type of the value is <code>String</code>, the result is the string
+	 * itself. If the expression does not have a compile-time constant expression
+	 * value, the result is <code>null</code>.
+	 * <p>
+	 * Resolving constant expressions takes into account the value of simple
+	 * and qualified names that refer to constant variables (JLS2 4.12.4).
+	 * </p>
+	 * <p>
+	 * Note 1: enum constants are not considered constant expressions either.
+	 * The result is always <code>null</code> for these.
+	 * </p>
+	 * <p>
+	 * Note 2: Compile-time constant expressions cannot denote <code>null</code>.
+	 * So technically {@link NullLiteral} nodes are not constant expressions.
+	 * The result is <code>null</code> for these nonetheless.
+	 * </p>
+	 * 
+	 * @return the constant expression value, or <code>null</code> if this
+	 * expression has no constant expression value or if bindings were not
+	 * requested when the AST was created
+	 * @since 3.1
+	 */
+	Object resolveConstantExpressionValue(Expression expression) {
+		return null;
+	}
+
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>ClassInstanceCreation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param expression the expression of interest
+	 * @return the binding for the constructor being invoked, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(ClassInstanceCreation expression) {
+		return null;
+	}
+	
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>ConstructorInvocation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param expression the expression of interest
+	 * @return the binding for the constructor being invoked, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(ConstructorInvocation expression) {
+		return null;
+	}
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>ConstructorInvocation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param enumConstantDeclaration the enum constant declaration of interest
+	 * @return the binding for the constructor being invoked, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(EnumConstantDeclaration enumConstantDeclaration) {
+		return null;
+	}
+	/**
+	 * Resolves and returns the binding for the constructor being invoked.
+	 * <p>
+	 * The implementation of
+	 * <code>SuperConstructorInvocation.resolveConstructor</code>
+	 * forwards to this method. Which constructor is invoked is often a function
+	 * of the context in which the expression node is embedded as well as
+	 * the expression subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param expression the expression of interest
+	 * @return the binding for the constructor being invoked, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveConstructor(SuperConstructorInvocation expression) {
+		return null;
+	}	
+	/**
+	 * Resolves the type of the given expression and returns the type binding
+	 * for it. 
+	 * <p>
+	 * The implementation of <code>Expression.resolveTypeBinding</code>
+	 * forwards to this method. The result is often a function of the context
+	 * in which the expression node is embedded as well as the expression 
+	 * subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param expression the expression whose type is of interest
+	 * @return the binding for the type of the given expression, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	ITypeBinding resolveExpressionType(Expression expression) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given field access and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>FieldAccess.resolveFieldBinding</code>
+	 * forwards to this method. How the field resolves is often a function of
+	 * the context in which the field access node is embedded as well as
+	 * the field access subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param fieldAccess the field access of interest
+	 * @return the binding for the given field access, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IVariableBinding resolveField(FieldAccess fieldAccess) {
+		return null;
+	}
+		
+	/**
+	 * Resolves the given super field access and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>SuperFieldAccess.resolveFieldBinding</code>
+	 * forwards to this method. How the field resolves is often a function of
+	 * the context in which the super field access node is embedded as well as
+	 * the super field access subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param fieldAccess the super field access of interest
+	 * @return the binding for the given field access, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IVariableBinding resolveField(SuperFieldAccess fieldAccess) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given import declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>ImportDeclaration.resolveBinding</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param importDeclaration the import declaration of interest
+	 * @return the binding for the given package declaration, or 
+	 *         the package binding (for on-demand imports) or type binding
+	 *         (for single-type imports), or <code>null</code> if no binding is
+	 *         available
+	 */
+	IBinding resolveImport(ImportDeclaration importDeclaration) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given annotation type declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AnnotationTypeMemberDeclaration.resolveBinding</code> 
+	 * forwards to this method. How the declaration resolves is often a 
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param member the annotation type member declaration of interest
+	 * @return the binding for the given annotation type member declaration, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.0
+	 */
+	IMethodBinding resolveMember(AnnotationTypeMemberDeclaration member) {
+		return null;
+	}
+		
+	/**
+	 * Resolves the given method declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodDeclaration.resolveBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method declaration node is embedded as well as
+	 * the method declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param method the method or constructor declaration of interest
+	 * @return the binding for the given method declaration, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(MethodDeclaration method) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given method invocation and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodInvocation.resolveMethodBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method invocation node is embedded as well as
+	 * the method invocation subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param method the method invocation of interest
+	 * @return the binding for the given method invocation, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(MethodInvocation method) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given method invocation and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodInvocation.resolveMethodBinding</code>
+	 * forwards to this method. How the method resolves is often a function of
+	 * the context in which the method invocation node is embedded as well as
+	 * the method invocation subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param method the method invocation of interest
+	 * @return the binding for the given method invocation, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IMethodBinding resolveMethod(SuperMethodInvocation method) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given name and returns the type binding for it.
+	 * <p>
+	 * The implementation of <code>Name.resolveBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param name the name of interest
+	 * @return the binding for the name, or <code>null</code> if no binding is
+	 *    available
+	 */
+	IBinding resolveName(Name name) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given package declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>PackageDeclaration.resolveBinding</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param pkg the package declaration of interest
+	 * @return the binding for the given package declaration, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IPackageBinding resolvePackage(PackageDeclaration pkg) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given reference and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MemberRef.resolveBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param ref the reference of interest
+	 * @return the binding for the reference, or <code>null</code> if no binding is
+	 *    available
+	 * @since 3.0
+	 */
+	IBinding resolveReference(MemberRef ref) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given reference and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>MethodRef.resolveBinding</code> forwards to
+	 * this method. How the name resolves is often a function of the context
+	 * in which the name node is embedded as well as the name itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param ref the reference of interest
+	 * @return the binding for the reference, or <code>null</code> if no binding is
+	 *    available
+	 * @since 3.0
+	 */
+	IBinding resolveReference(MethodRef ref) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given annotation type declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AnnotationTypeDeclaration.resolveBinding</code> 
+	 * forwards to this method. How the declaration resolves is often a 
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param type the annotation type declaration of interest
+	 * @return the binding for the given annotation type declaration, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.0
+	 */
+	ITypeBinding resolveType(AnnotationTypeDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given anonymous class declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AnonymousClassDeclaration.resolveBinding</code> 
+	 * forwards to this method. How the declaration resolves is often a 
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param type the anonymous class declaration of interest
+	 * @return the binding for the given class declaration, or <code>null</code>
+	 *    if no binding is available
+	 */
+	ITypeBinding resolveType(AnonymousClassDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given enum declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>EnumDeclaration.resolveBinding</code> 
+	 * forwards to this method. How the enum declaration resolves is often
+	 * a function of the context in which the declaration node is embedded
+	 * as well as the enum declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param type the enum declaration of interest
+	 * @return the binding for the given enum declaration, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.0
+	 */
+	ITypeBinding resolveType(EnumDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given type and returns the type binding for it.
+	 * <p>
+	 * The implementation of <code>Type.resolveBinding</code>
+	 * forwards to this method. How the type resolves is often a function
+	 * of the context in which the type node is embedded as well as the type
+	 * subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param type the type of interest
+	 * @return the binding for the given type, or <code>null</code>
+	 *    if no binding is available 
+	 */
+	ITypeBinding resolveType(Type type) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given class or interface declaration and returns the binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>TypeDeclaration.resolveBinding</code> 
+	 * (and <code>TypeDeclarationStatement.resolveBinding</code>) forwards
+	 * to this method. How the type declaration resolves is often a function of
+	 * the context in which the type declaration node is embedded as well as the
+	 * type declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param type the class or interface declaration of interest
+	 * @return the binding for the given type declaration, or <code>null</code>
+	 *    if no binding is available
+	 */
+	ITypeBinding resolveType(TypeDeclaration type) {
+		return null;
+	}
+
+	/**
+	 * Resolves the given type parameter and returns the type binding for the
+	 * type parameter.
+	 * <p>
+	 * The implementation of <code>TypeParameter.resolveBinding</code> 
+	 * forwards to this method. How the declaration resolves is often a 
+	 * function of the context in which the declaration node is embedded as well
+	 * as the declaration subtree itself.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param typeParameter the type paramter of interest
+	 * @return the binding for the given type parameter, or <code>null</code>
+	 *    if no binding is available
+	 * @since 3.1
+	 */
+	ITypeBinding resolveTypeParameter(TypeParameter typeParameter) {
+		return null;
+	}		
+
+	/**
+	 * Resolves the given enum constant declaration and returns the binding for
+	 * the field.
+	 * <p>
+	 * The implementation of <code>EnumConstantDeclaration.resolveVariable</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param enumConstant the enum constant declaration of interest
+	 * @return the field binding for the given enum constant declaration, or 
+	 *    <code>null</code> if no binding is available
+	 * @since 3.0
+	 */
+	IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given variable declaration and returns the binding for it.
+	 * <p>
+	 * The implementation of <code>VariableDeclaration.resolveBinding</code>
+	 * forwards to this method. How the variable declaration resolves is often
+	 * a function of the context in which the variable declaration node is 
+	 * embedded as well as the variable declaration subtree itself. VariableDeclaration 
+	 * declarations used as local variable, formal parameter and exception 
+	 * variables resolve to local variable bindings; variable declarations
+	 * used to declare fields resolve to field bindings.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param variable the variable declaration of interest
+	 * @return the binding for the given variable declaration, or 
+	 *    <code>null</code> if no binding is available
+	 */
+	IVariableBinding resolveVariable(VariableDeclaration variable) {
+		return null;
+	}
+	
+	/**
+	 * Resolves the given well known type by name and returns the type binding
+	 * for it.
+	 * <p>
+	 * The implementation of <code>AST.resolveWellKnownType</code>
+	 * forwards to this method.
+	 * </p>
+	 * <p>
+	 * The default implementation of this method returns <code>null</code>.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param name the name of a well known type
+	 * @return the corresponding type binding, or <code>null<code> if the 
+	 *   named type is not considered well known or if no binding can be found
+	 *   for it
+	 */
+	ITypeBinding resolveWellKnownType(String name) {
+		return null;
+	}
+	
+	/**
+	 * Returns the compilation unit scope used by this binding resolver.
+	 * Returns <code>null</code> if none.
+	 * 
+	 * @return the compilation unit scope by this resolver, or <code>null</code> if none.
+	 */
+	public CompilationUnitScope scope() {
+		return null;
+	}
+	
+	/**
+	 * Allows the user to store information about the given old/new pair of
+	 * AST nodes.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses may reimplement.
+	 * </p>
+	 * 
+	 * @param newNode the new AST node
+	 * @param oldASTNode the old AST node
+	 */
+	void store(ASTNode newNode, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) {
+		// default implementation: do nothing
+	} 
+
+	/**
 	 * Allows the user to update information about the given old/new pair of
 	 * AST nodes.
 	 * <p>
@@ -713,31 +823,4 @@
 	void updateKey(ASTNode node, ASTNode newNode) {
 		// default implementation: do nothing
 	}
-	
-	/**
-	 * Allows the user to get information about the given old/new pair of
-	 * AST nodes.
-	 * <p>
-	 * The default implementation of this method does nothing.
-	 * Subclasses may reimplement.
-	 * </p>
-	 *
-	 * @param currentNode the new node
-	 * @return org.eclipse.jdt.internal.compiler.ast.ASTNode
-	 */
-	org.eclipse.jdt.internal.compiler.ast.ASTNode getCorrespondingNode(ASTNode currentNode) {
-		return null;
-	} 
-
-	/**
-	 * This method is used to record the scope and its corresponding node.
-	 * <p>
-	 * The default implementation of this method does nothing.
-	 * Subclasses may reimplement.
-	 * </p>
-	 * @param astNode
-	 */	
-	void recordScope(ASTNode astNode, BlockScope blockScope) {
-		// default implementation: do nothing
-	}
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java
index c9afc2b..f8a3528 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Block.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java
index 583c9aa..314a554 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BlockComment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java
index 28b614b..46d6ad5 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BodyDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -231,16 +231,26 @@
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
 	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link #modifiers()} which contains a list of a <code>Modifier</code> nodes.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>modifiers()</code> which contains a list of a <code>Modifier</code> nodes.
 	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
 		// more efficient than just calling supportedOnlyIn2() to check
 		if (this.modifiers != null) {
 			supportedOnlyIn2();
 		}
 		SimplePropertyDescriptor p = internalModifiersProperty();
 		preValueChange(p);
-		this.modifierFlags = modifiers;
+		this.modifierFlags = pmodifiers;
 		postValueChange(p);
 	}
 
@@ -252,7 +262,7 @@
 	 *    (element type: <code>IExtendedModifier</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List modifiers() {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java
index 6a16ea2..1c920bf 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BooleanLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
index 178e26b..23bc47c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java
index 3643cc3..3de5013 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CastExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java
index cca0527..bdf34eb 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CatchClause.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
index c49e7be..7431400 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CharacterLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -162,6 +162,7 @@
 	 * @exception IllegalArgumentException if the argument is incorrect
 	 */ 
 	public void setEscapedValue(String value) {
+		// check setInternalEscapedValue(String) if this method is changed
 		if (value == null) {
 			throw new IllegalArgumentException();
 		}
@@ -185,6 +186,16 @@
 		postValueChange(ESCAPED_VALUE_PROPERTY);
 	}
 
+
+	/* (omit javadoc for this method)
+	 * This method is a copy of setEscapedValue(String) that doesn't do any validation.
+	 */
+	void internalSetEscapedValue(String value) {
+		preValueChange(ESCAPED_VALUE_PROPERTY);
+		this.escapedValue = value;
+		postValueChange(ESCAPED_VALUE_PROPERTY);
+	}
+
 	/**
 	 * Returns the value of this literal node. 
 	 * <p>
@@ -201,81 +212,86 @@
 	 * @exception IllegalArgumentException if the literal value cannot be converted
 	 */ 
 	public char charValue() {
-		String s = getEscapedValue();
-		int len = s.length();
-		if (len < 2 || s.charAt(0) != '\'' || s.charAt(len-1) != '\'' ) {
-			throw new IllegalArgumentException();
+		Scanner scanner = this.ast.scanner;
+		char[] source = escapedValue.toCharArray();
+		scanner.setSource(source);
+		scanner.resetTo(0, source.length);
+		int firstChar = scanner.getNextChar();
+		int secondChar = scanner.getNextChar();
+
+		if (firstChar == -1 || firstChar != '\'') {
+			throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
 		}
-		char c = s.charAt(1);
-		if (c == '\'') {
-			throw new IllegalArgumentException();
-		}
-		if (c == '\\') {
-			if (len == 4) {
-				char nextChar = s.charAt(2);
-				switch(nextChar) {
-					case 'b' :
-						return '\b';
-					case 't' :
-						return '\t';
-					case 'n' :
-						return '\n';
-					case 'f' :
-						return '\f';
-					case 'r' :
-						return '\r';
-					case '\"':
-						return '\"';
-					case '\'':
-						return '\'';
-					case '\\':
-						return '\\';
-					case '0' :
-						return '\0';
-					case '1' :
-						return '\1';
-					case '2' :
-						return '\2';
-					case '3' :
-						return '\3';
-					case '4' :
-						return '\4';
-					case '5' :
-						return '\5';
-					case '6' :
-						return '\6';
-					case '7' :
-						return '\7';
-					default:
-						throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
-				}
-			} else if (len == 8) {
-				//handle the case of unicode.
-				int currentPosition = 2;
-				int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-				if (s.charAt(currentPosition++) == 'u') {
-					if ((c1 = Character.getNumericValue(s.charAt(currentPosition++))) > 15
-						|| c1 < 0
-						|| (c2 = Character.getNumericValue(s.charAt(currentPosition++))) > 15
-						|| c2 < 0
-						|| (c3 = Character.getNumericValue(s.charAt(currentPosition++))) > 15
-						|| c3 < 0
-						|| (c4 = Character.getNumericValue(s.charAt(currentPosition++))) > 15
-						|| c4 < 0){
-						throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+		char value = (char) secondChar;
+		char nextChar = (char) scanner.getNextChar();
+		if (secondChar == '\\') {
+			if (nextChar == -1) {
+				throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+			}
+			switch(nextChar) {
+				case 'b' :
+					value = '\b';
+					break;
+				case 't' :
+					value = '\t';
+					break;
+				case 'n' :
+					value = '\n';
+					break;
+				case 'f' :
+					value = '\f';
+					break;
+				case 'r' :
+					value = '\r';
+					break;
+				case '\"':
+					value = '\"';
+					break;
+				case '\'':
+					value = '\'';
+					break;
+				case '\\':
+					value = '\\';
+					break;
+				default : //octal (well-formed: ended by a ' )
+					if (Character.isDigit(nextChar)) {
+						int number = Character.getNumericValue(nextChar);
+						nextChar = (char) scanner.getNextChar();
+						if (nextChar == -1) {
+							throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+						}
+						if (nextChar != '\'') {
+							if (!Character.isDigit(nextChar)) {
+								throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+							}
+							number = (number * 8) + Character.getNumericValue(nextChar);
+						}
+						nextChar = (char) scanner.getNextChar();
+						if (nextChar == -1) {
+							throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+						}
+						if (nextChar != '\'') {
+							if (!Character.isDigit(nextChar)) {
+								throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+							}
+							number = (number * 8) + Character.getNumericValue(nextChar);
+						}
+						value = (char) number;
 					} else {
-						return (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+						throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
 					}
-				} else {
-					throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
-				}
-			} else {
+					break;
+			}
+			nextChar = (char) scanner.getNextChar();
+			if (nextChar == -1) {
 				throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
 			}
 		}
-		return c;
+		if (nextChar == -1 || nextChar != '\'') {
+			throw new IllegalArgumentException("illegal character literal");//$NON-NLS-1$
+		}
+		return value;
 	}
-
 	/**
 	 * Sets the value of this character literal node to the given character. 
 	 * <p>
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java
index 39d7944..18ecaa8 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildListPropertyDescriptor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -94,4 +94,4 @@
 	public final boolean cycleRisk() {
 		return this.cycleRisk;
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java
index a58ec5a..8e33777 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ChildPropertyDescriptor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
index 3b4fb0a..8463185 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -63,7 +63,7 @@
 
 	/**
 	 * The "typeArguments" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
 		new ChildListPropertyDescriptor(ClassInstanceCreation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -79,13 +79,12 @@
 	 * The "name" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #TYPE_PROPERTY} in the JLS3 API.
 	public static final ChildPropertyDescriptor NAME_PROPERTY = 
 		new ChildPropertyDescriptor(ClassInstanceCreation.class, "name", Name.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "type" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildPropertyDescriptor TYPE_PROPERTY = 
 		new ChildPropertyDescriptor(ClassInstanceCreation.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -116,7 +115,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -151,7 +150,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -167,7 +166,7 @@
 	 * The type arguments (element type: <code>Type</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeArguments = null;
 
@@ -294,7 +293,7 @@
 		result.setSourceRange(this.getStartPosition(), this.getLength());
 		result.setExpression(
 			(Expression) ASTNode.copySubtree(target, getExpression()));
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			result.setName((Name) getName().clone(target));
 		}
 		if (this.ast.apiLevel >= AST.JLS3) {
@@ -324,7 +323,7 @@
 		if (visitChildren) {
 			// visit children in normal left to right reading order
 			acceptChild(visitor, getExpression());
-			if (this.ast.apiLevel == AST.JLS2) {
+			if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 				acceptChild(visitor, getName());
 			}
 			if (this.ast.apiLevel >= AST.JLS3) {
@@ -371,18 +370,12 @@
 	/**
 	 * Returns the live ordered list of type arguments of this class
 	 * instance creation (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type arguments
 	 *    (element type: <code>Type</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeArguments() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -399,9 +392,20 @@
 	 * @return the type name node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #getType()}, which returns a <code>Type</code> instead of a
+	 * <code>Name</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>getType</code>, which returns a <code>Type</code> instead of a <code>Name</code>.
 	public Name getName() {
+		return internalGetName();
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ Name internalGetName() {
 	    supportedOnlyIn2();
 		if (this.typeName == null) {
 			// lazy init must be thread-safe for readers
@@ -428,9 +432,20 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link #setType(Type)}, which expects a <code>Type</code> instead of
+	 * a <code>Name</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>setType</code>, which expects a <code>Type</code> instead of a <code>Name</code>.
 	public void setName(Name name) {
+		internalSetName(name);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ public void internalSetName(Name name) {
 	    supportedOnlyIn2();
 		if (name == null) {
 			throw new IllegalArgumentException();
@@ -448,7 +463,7 @@
 	 * @return the type node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public Type getType() {
 	    unsupportedIn2();
@@ -477,7 +492,7 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public void setType(Type type) {
 	    unsupportedIn2();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java
index 93fbbc2..a0e1ac9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Comment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
index aed0638..5306d06 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,6 +17,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
 import org.eclipse.jface.text.IDocument;
@@ -170,13 +171,20 @@
 	private IProblem[] problems = EMPTY_PROBLEMS;
 	
 	/**
-	 * The comment mapper, or <code>null</code> in none; 
+	 * The comment mapper, or <code>null</code> if none; 
 	 * initially <code>null</code>.
 	 * @since 3.0
 	 */
 	private DefaultCommentMapper commentMapper = null;
 	
 	/**
+	 * The Java element (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or an <code>org.eclipse.jdt.core.IClassFile</code>) 
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java element.
+	 * @since 3.1
+	 */
+	private IJavaElement element = null;
+	
+	/**
 	 * Sets the line end table for this compilation unit.
 	 * If <code>lineEndTable[i] == p</code> then line number <code>i+1</code> 
 	 * ends at character position <code>p</code>. Except for the last line, the 
@@ -340,7 +348,7 @@
 	 * compilation unit, in order of appearance.
      * <p>
      * Note that in JLS3, the types may include both enum declarations
-     * and annotation type declarations introduced in J2SE 1.5.
+     * and annotation type declarations introduced in J2SE 5.
      * For JLS2, the elements are always <code>TypeDeclaration</code>.
      * </p>
 	 * 
@@ -361,7 +369,6 @@
 	 * The following table indicates the expected node type for the various
 	 * different kinds of bindings:
 	 * <ul>
-	 * <li></li>
 	 * <li>package - a <code>PackageDeclaration</code></li>
 	 * <li>class or interface - a <code>TypeDeclaration</code> or a
 	 *    <code>AnonymousClassDeclaration</code> (for anonymous classes)</li>
@@ -373,14 +380,19 @@
 	 *    a <code>VariableDeclarationFragment</code> in a 
 	 *    <code>VariableDeclarationStatement</code> or 
 	 *    <code>VariableDeclarationExpression</code></li>
-	 * <li>method - a <code>MethodDeclaration</code> </li>
+	 * <li>methods - a <code>MethodDeclaration</code> </li>
 	 * <li>constructor - a <code>MethodDeclaration</code> </li>
      * <li>annotation type - an <code>AnnotationTypeDeclaration</code></li>
      * <li>annotation type member - an <code>AnnotationTypeMemberDeclaration</code></li>
      * <li>enum type - an <code>EnumDeclaration</code></li>
      * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
-	 * <li>type variable - a <code>TypeParameter</code></li>
+     * <li>type variable - a <code>TypeParameter</code></li>
+     * <li>capture binding - none</li>
 	 * </ul>
+     * For parameterized or raw type bindings, the declaring node is
+     * that of the corresponding generic type. And for parameterized or raw
+     * method bindings, the declaring node is that of the corresponding
+     * generic method.
 	 * </p>
 	 * <p>
 	 * Each call to {@link ASTParser#createAST(org.eclipse.core.runtime.IProgressMonitor)} with a request for bindings
@@ -429,12 +441,12 @@
      * <li>enum type - an <code>EnumDeclaration</code></li>
      * <li>enum constant - an <code>EnumConstantDeclaration</code></li>
 	 * <li>type variable - a <code>TypeParameter</code></li>
+     * <li>capture binding - none</li>
 	 * </ul>
-	 * </p>
-	 * <p>
-	 * Note that as explained in {@link IBinding#getKey() IBinding.getkey}
-	 * there may be no keys for finding the declaring node for local variables,
-	 * local or anonymous classes, etc.
+     * For parameterized or raw type bindings, the declaring node is
+     * that of the corresponding generic type. And for parameterized or raw
+     * method bindings, the declaring node is that of the corresponding
+     * generic method.
 	 * </p>
 	 * 
 	 * @param key the binding key, or <code>null</code>
@@ -484,8 +496,12 @@
 	 * @since 3.0
 	 */
 	public int getExtendedStartPosition(ASTNode node) {
-		if (this.commentMapper == null) {
-			return -1;
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.commentMapper == null || node.getAST() != getAST()) {
+			// fall back: use best info available
+			return node.getStartPosition();
 		} else {
 			return this.commentMapper.getExtendedStartPosition(node);
 		}
@@ -504,8 +520,12 @@
 	 * @since 3.0
 	 */
 	public int getExtendedLength(ASTNode node) {
-		if (this.commentMapper == null) {
-			return 0;
+		if (node == null) {
+			throw new IllegalArgumentException();
+		}
+		if (this.commentMapper == null || node.getAST() != getAST()) {
+			// fall back: use best info available
+			return node.getLength();
 		} else {
 			return this.commentMapper.getExtendedLength(node);
 		}
@@ -584,6 +604,17 @@
 	}
 
 	/**
+	 * The Java element (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or an <code>org.eclipse.jdt.core.IClassFile</code>) 
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java element.
+	 * 
+	 * @return the Java element this compilation unit was created from, or <code>null</code> if none
+	 * @since 3.1
+	 */
+	public IJavaElement getJavaElement() {
+		return this.element;
+	}
+	
+	/**
 	 * Returns the list of messages reported by the compiler during the parsing 
 	 * or the type checking of this compilation unit. This list might be a subset of 
 	 * errors detected and reported by a Java compiler.
@@ -738,6 +769,18 @@
 			this.optionalCommentList = Collections.unmodifiableList(commentList);
 		}
 	}
+	
+	/**
+	 * Sets the Java element (an <code>org.eclipse.jdt.core.ICompilationUnit</code> or an <code>org.eclipse.jdt.core.IClassFile</code>) 
+	 * this compilation unit was created from, or <code>null</code> if it was not created from a Java element.
+	 * 
+	 * @param element the Java element this compilation unit was created from
+	 * @since 3.1
+	 */
+	void setJavaElement(IJavaElement element) {
+		this.element = element;
+	}
+
 
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
index abf5207..3e5898d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/CompilationUnitResolver.java
@@ -1,24 +1,28 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-
 package org.eclipse.jdt.core.dom;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.WorkingCopyOwner;
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.Compiler;
 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
@@ -31,7 +35,6 @@
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.env.ISourceType;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
@@ -40,16 +43,33 @@
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
+import org.eclipse.jdt.internal.compiler.util.Messages;
+import org.eclipse.jdt.internal.core.BinaryMember;
 import org.eclipse.jdt.internal.core.CancelableNameEnvironment;
 import org.eclipse.jdt.internal.core.CancelableProblemFactory;
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.internal.core.NameLookup;
+import org.eclipse.jdt.internal.core.SourceRefElement;
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
+import org.eclipse.jdt.internal.core.util.BindingKeyResolver;
 import org.eclipse.jdt.internal.core.util.CommentRecorderParser;
+import org.eclipse.jdt.internal.core.util.DOMFinder;
 
 class CompilationUnitResolver extends Compiler {
 	
+	/* A list of int */
+	static class IntArrayList {
+		public int[] list = new int[5];
+		public int length = 0;
+		public void add(int i) {
+			if (this.list.length == this.length) {
+				System.arraycopy(this.list, 0, this.list = new int[this.length*2], 0, this.length);
+			}
+				this.list[this.length++] = i;
+			}
+		}
+		
 	/*
 	 * The sources that were requested.
 	 * Map from file name (char[]) to ICompilationUnit.
@@ -58,11 +78,13 @@
 	
 	/*
 	 * The binding keys that were requested.
-	 * Map from file name (char[]) to BindingKey.
+	 * Map from file name (char[]) to BindingKey (or ArrayList if multiple keys in the same file).
 	 */
 	HashtableOfObject requestedKeys;
 	
 	DefaultBindingResolver.BindingTables bindingTables;
+	
+	boolean hasCompilationAborted;
 
 	/**
 	 * Answer a new CompilationUnitVisitor using the given name environment and compiler options.
@@ -107,6 +129,7 @@
 		IProblemFactory problemFactory) {
 
 		super(environment, policy, settings, requestor, problemFactory, false);
+		this.hasCompilationAborted = false;
 	}
 	
 	/*
@@ -141,12 +164,12 @@
 			try {
 				if (options.verbose) {
 					System.out.println(
-						Util.bind(
-							"compilation.request" , //$NON-NLS-1$
-							new String[] {
-								String.valueOf(index++ + 1),
-								String.valueOf(maxUnits),
-								new String(sourceUnit.getFileName())}));
+						Messages.bind(Messages.compilation_request,
+						new String[] {
+							String.valueOf(index++ + 1),
+							String.valueOf(maxUnits),
+							new String(sourceUnit.getFileName())
+						}));
 				}
 				// diet parsing for large collection of units
 				if (this.totalUnits < this.parseThreshold) {
@@ -166,22 +189,32 @@
 		// walk the binding keys
 		this.requestedKeys = new HashtableOfObject();
 		for (int i = 0; i < keyLength; i++) {
-			BindingKey bindingKey = new BindingKey(bindingKeys[i], this);
-			CompilationUnitDeclaration parsedUnit = bindingKey.getCompilationUnitDeclaration();
+			BindingKeyResolver resolver = new BindingKeyResolver(bindingKeys[i], this, this.lookupEnvironment);
+			resolver.parse(true/*pause after fully qualified name*/);
+			CompilationUnitDeclaration parsedUnit = resolver.getCompilationUnitDeclaration();
 			if (parsedUnit != null) {
-				this.requestedKeys.put(parsedUnit.compilationResult.getFileName(), bindingKey);
+				char[] fileName = parsedUnit.compilationResult.getFileName();
+				Object existing = this.requestedKeys.get(fileName);
+				if (existing == null)
+					this.requestedKeys.put(fileName, resolver);
+				else if (existing instanceof ArrayList)
+					((ArrayList) existing).add(resolver);
+				else {
+					ArrayList list = new ArrayList();
+					list.add(existing);
+					list.add(resolver);
+					this.requestedKeys.put(fileName, list);
+				} 
+					
 			} else {
-				switch (bindingKey.scanner.token) {
-					case BindingKeyScanner.PACKAGE:
-						// package binding key
-						char[] pkgName = CharOperation.concatWith(bindingKey.compoundName(), '.');
-						this.requestedKeys.put(pkgName, bindingKey);
-						break;
-					case BindingKeyScanner.TYPE:
-						// base type binding
-						char[] key = bindingKey.scanner.source;
-						this.requestedKeys.put(key, bindingKey);
-						break;
+				if (!resolver.hasTypeName()) {
+					// package binding key
+					char[] pkgName = CharOperation.concatWith(resolver.compoundName(), '.');
+					this.requestedKeys.put(pkgName, resolver);
+				} else {
+					// base type binding or binary binding
+					char[] key = resolver.getKey().toCharArray();
+					this.requestedKeys.put(key, resolver);
 				}
 			}
 		}
@@ -193,18 +226,14 @@
 	IBinding createBinding(String key) {
 		if (this.bindingTables == null)
 			throw new RuntimeException("Cannot be called outside ASTParser#createASTs(...)"); //$NON-NLS-1$
-		BindingKey bindingKey = new BindingKey(key, this);
-		Binding compilerBinding = bindingKey.getCompilerBinding();
+		BindingKeyResolver keyResolver = new BindingKeyResolver(key, this, this.lookupEnvironment);
+		Binding compilerBinding = keyResolver.getCompilerBinding();
 		if (compilerBinding == null) return null;
 		DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, null/*no owner*/, this.bindingTables);
-		if (compilerBinding.kind() == Binding.ARRAY_TYPE) {
-			return new TypeBinding(resolver, (ArrayBinding) compilerBinding);
-		} else {
-			return resolver.getBinding(compilerBinding);
-		}
+		return resolver.getBinding(compilerBinding);
 	}
 	
-	public static ASTNode convert(CompilationUnitDeclaration compilationUnitDeclaration, char[] source, int apiLevel, Map options, boolean needToResolveBindings, WorkingCopyOwner owner, DefaultBindingResolver.BindingTables bindingTables, IProgressMonitor monitor) {
+	public static CompilationUnit convert(CompilationUnitDeclaration compilationUnitDeclaration, char[] source, int apiLevel, Map options, boolean needToResolveBindings, WorkingCopyOwner owner, DefaultBindingResolver.BindingTables bindingTables, IProgressMonitor monitor) {
 		BindingResolver resolver = null;
 		AST ast = AST.newAST(apiLevel);
 		ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
@@ -257,6 +286,12 @@
 	public void initializeParser() {
 		this.parser = new CommentRecorderParser(this.problemReporter, false);
 	}
+	public void process(CompilationUnitDeclaration unit, int i) {
+		// don't resolve a second time the same unit (this would create the same binding twice)
+		char[] fileName = unit.compilationResult.getFileName();
+		if (!this.requestedKeys.containsKey(fileName) && !this.requestedSources.containsKey(fileName))
+			super.process(unit, i);
+	}
 	/*
 	 * Compiler crash recovery in case of unexpected runtime exceptions
 	 */
@@ -280,6 +315,7 @@
 		if (unit != null) {
 			removeUnresolvedBindings(unit);
 		}
+		this.hasCompilationAborted = true;
 	}	
 	
 	public static void parse(ICompilationUnit[] compilationUnits, ASTRequestor astRequestor, int apiLevel, Map options, IProgressMonitor monitor) {
@@ -311,11 +347,12 @@
 			}
 			
 			// convert AST
-			ASTNode node = convert(compilationUnitDeclaration, sourceUnit.getContents(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, monitor);
+			CompilationUnit node = convert(compilationUnitDeclaration, sourceUnit.getContents(), apiLevel, options, false/*don't resolve binding*/, null/*no owner needed*/, null/*no binding table needed*/, monitor);
+			node.setJavaElement(compilationUnits[i]);
 			
 			
 			// accept AST
-			astRequestor.acceptAST(compilationUnits[i], (CompilationUnit) node);
+			astRequestor.acceptAST(compilationUnits[i], node);
 		}
 	}
 	
@@ -402,8 +439,10 @@
 					problemFactory);
 
 			resolver.resolve(compilationUnits, bindingKeys, requestor, apiLevel, options, owner, monitor);
-			if (NameLookup.VERBOSE)
+			if (NameLookup.VERBOSE) {
 				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+			}
 		} catch (JavaModelException e) {
 			// project doesn't exist -> simple parse without resolving
 			parse(compilationUnits, requestor, apiLevel, options, monitor);
@@ -422,16 +461,16 @@
 		NodeSearcher nodeSearcher,
 		Map options,
 		WorkingCopyOwner owner,
-		IProgressMonitor monitor)
-		throws JavaModelException {
+		IProgressMonitor monitor) throws JavaModelException {
 	
 		CompilationUnitDeclaration unit = null;
 		CancelableNameEnvironment environment = null;
 		CancelableProblemFactory problemFactory = null;
+		CompilationUnitResolver resolver = null;
 		try {
 			environment = new CancelableNameEnvironment(((JavaProject)javaProject), owner, monitor);
 			problemFactory = new CancelableProblemFactory(monitor);
-			CompilationUnitResolver resolver =
+			resolver =
 				new CompilationUnitResolver(
 					environment,
 					getHandlingPolicy(),
@@ -446,9 +485,23 @@
 					nodeSearcher,
 					true, // method verification
 					true, // analyze code
-					true); // generate code					
-			if (NameLookup.VERBOSE)
+					true); // generate code
+			if (resolver.hasCompilationAborted) {
+				// the bindings could not be resolved due to missing types in name environment
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=86541
+				CompilationUnitDeclaration unitDeclaration = parse(sourceUnit, nodeSearcher, options);
+				final int problemCount = unit.compilationResult.problemCount;
+				if (problemCount != 0) {
+					unitDeclaration.compilationResult.problems = new IProblem[problemCount];
+					System.arraycopy(unit.compilationResult.problems, 0, unitDeclaration.compilationResult.problems, 0, problemCount);
+					unitDeclaration.compilationResult.problemCount = problemCount;
+				}
+				return unitDeclaration;
+			}
+			if (NameLookup.VERBOSE) {
 				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+			}	
 			return unit;
 		} finally {
 			if (environment != null) {
@@ -457,9 +510,85 @@
 			if (problemFactory != null) {
 				problemFactory.monitor = null; // don't hold a reference to this external object
 			}
-			// unit cleanup is done by caller
+			// first unit cleanup is done by caller, but cleanup all enqueued requested units (not processed)
+//			if (resolver != null) {
+//				for (int i = 1; i <  resolver.totalUnits; i++) { // could be more requested units
+//					CompilationUnitDeclaration parsedUnit = resolver.unitsToProcess[i];
+//					if (parsedUnit.scope != null) 
+//						parsedUnit.scope.faultInTypes(); // force resolution of signatures, so clients can query DOM AST
+//					parsedUnit.cleanUp();
+//				}
+//			}
 		}
 	}
+	public static IBinding[] resolve(
+		final IJavaElement[] elements,
+		int apiLevel,
+		Map compilerOptions,
+		IJavaProject javaProject,
+		WorkingCopyOwner owner,
+		IProgressMonitor monitor) {
+
+		final int length = elements.length;
+		final HashMap sourceElementPositions = new HashMap(); // a map from ICompilationUnit to int[] (positions in elements)
+		int cuNumber = 0;
+		final HashtableOfObjectToInt binaryElementPositions = new HashtableOfObjectToInt(); // a map from String (binding key) to int (position in elements)
+		for (int i = 0; i < length; i++) {
+			IJavaElement element = elements[i];
+			if (!(element instanceof SourceRefElement))
+				throw new IllegalStateException(element + " is not part of a compilation unit or class file"); //$NON-NLS-1$
+			Object cu = element.getAncestor(IJavaElement.COMPILATION_UNIT);
+			if (cu != null) {
+				// source member
+				IntArrayList intList = (IntArrayList) sourceElementPositions.get(cu);
+				if (intList == null) {
+					sourceElementPositions.put(cu, intList = new IntArrayList());
+					cuNumber++;
+				}
+				intList.add(i);
+			} else {
+				// binary member
+				try {
+					String key = ((BinaryMember) element).getKey(true/*open to get resolved info*/);
+					binaryElementPositions.put(key, i);
+				} catch (JavaModelException e) {
+					throw new IllegalArgumentException(element + " does not exist"); //$NON-NLS-1$
+				}
+			}	
+		}
+		ICompilationUnit[] cus = new ICompilationUnit[cuNumber];
+		sourceElementPositions.keySet().toArray(cus);
+		
+		int bindingKeyNumber = binaryElementPositions.size();
+		String[] bindingKeys = new String[bindingKeyNumber];
+		binaryElementPositions.keysToArray(bindingKeys);
+		
+		class Requestor extends ASTRequestor {
+			IBinding[] bindings = new IBinding[length];
+			public void acceptAST(ICompilationUnit source, CompilationUnit ast) {
+				// TODO (jerome) optimize to visit the AST only once
+				IntArrayList intList = (IntArrayList) sourceElementPositions.get(source);
+				for (int i = 0; i < intList.length; i++) {
+					final int index = intList.list[i];
+					SourceRefElement element = (SourceRefElement) elements[index];
+					DOMFinder finder = new DOMFinder(ast, element, true/*resolve binding*/);
+					try {
+						finder.search();
+					} catch (JavaModelException e) {
+						throw new IllegalArgumentException(element + " does not exist"); //$NON-NLS-1$
+					}
+					this.bindings[index] = finder.foundBinding;
+				}
+			}
+			public void acceptBinding(String bindingKey, IBinding binding) {
+				int index = binaryElementPositions.get(bindingKey);
+				this.bindings[index] = binding;
+			}
+		}
+		Requestor requestor = new Requestor();
+		resolve(cus, bindingKeys, requestor, apiLevel, compilerOptions, javaProject, owner, monitor);
+		return requestor.bindings;
+	}
 	/*
 	 * When unit result is about to be accepted, removed back pointers
 	 * to unresolved bindings
@@ -518,40 +647,46 @@
 			for (; i < this.totalUnits; i++) {
 				unit = this.unitsToProcess[i];
 				try {
-					process(unit, i);
+					char[] fileName = unit.compilationResult.getFileName();
 					
-					ICompilationUnit source = (ICompilationUnit) this.requestedSources.removeKey(unit.compilationResult.getFileName());
-					if (source != null) {
-						// convert AST
-						CompilationResult compilationResult = unit.compilationResult;
-						org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationResult.compilationUnit;
-						char[] contents = sourceUnit.getContents();
-						AST ast = AST.newAST(apiLevel);
-						ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
-						ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, monitor);
-						BindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables);
-						ast.setBindingResolver(resolver);
-						converter.setAST(ast);
-						CompilationUnit compilationUnit = converter.convert(unit, contents);
-						compilationUnit.setLineEndTable(compilationResult.lineSeparatorPositions);
-						ast.setDefaultNodeFlag(0);
-						ast.setOriginalModificationCount(ast.modificationCount());
+					// only process requested units
+					if (this.requestedKeys.containsKey(fileName) || this.requestedSources.containsKey(fileName)) {
+						super.process(unit, i); // this.process(...) is optimized to not process already known units
 						
-						// pass it to requestor
-						astRequestor.acceptAST(source, compilationUnit);
-					} 
-					
-					BindingKey bindingKey = (BindingKey) this.requestedKeys.removeKey(unit.compilationResult.getFileName());
-					if (bindingKey != null) {
-						Binding compilerBinding = bindingKey.getCompilerBinding(unit);
-						if (compilerBinding != null) {
-							DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables);
-							IBinding binding = resolver.getBinding(compilerBinding);
+						ICompilationUnit source = (ICompilationUnit) this.requestedSources.removeKey(fileName);
+						if (source != null) {
+							// convert AST
+							CompilationResult compilationResult = unit.compilationResult;
+							org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = compilationResult.compilationUnit;
+							char[] contents = sourceUnit.getContents();
+							AST ast = AST.newAST(apiLevel);
+							ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
+							ASTConverter converter = new ASTConverter(compilerOptions, true/*need to resolve bindings*/, monitor);
+							BindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables);
+							ast.setBindingResolver(resolver);
+							converter.setAST(ast);
+							CompilationUnit compilationUnit = converter.convert(unit, contents);
+							compilationUnit.setJavaElement(source);
+							compilationUnit.setLineEndTable(compilationResult.lineSeparatorPositions);
+							ast.setDefaultNodeFlag(0);
+							ast.setOriginalModificationCount(ast.modificationCount());
 							
 							// pass it to requestor
-							if (binding != null)
-								astRequestor.acceptBinding(bindingKey.getKey(), binding);
+							astRequestor.acceptAST(source, compilationUnit);
+						} 
+						
+						Object key = this.requestedKeys.removeKey(fileName);
+						if (key instanceof BindingKeyResolver) {
+							reportBinding(key, astRequestor, owner, unit);
+						} else if (key instanceof ArrayList) {
+							Iterator iterator = ((ArrayList) key).iterator();
+							while (iterator.hasNext()) {
+								reportBinding(iterator.next(), astRequestor, owner, unit);
+							}
 						}
+					} else {
+						if (unit.scope != null)
+							unit.scope.faultInTypes(); // still force resolution of signatures, so clients can query DOM AST
 					}
 				} finally {
 					// cleanup compilation unit result
@@ -565,15 +700,12 @@
 			DefaultBindingResolver resolver = new DefaultBindingResolver(this.lookupEnvironment, owner, this.bindingTables);
 			Object[] keys = this.requestedKeys.valueTable;
 			for (int j = 0, keysLength = keys.length; j < keysLength; j++) {
-				BindingKey key = (BindingKey) keys[j];
-				if (key == null) continue;
-				Binding compilerBinding = key.getCompilerBinding();
-				if (compilerBinding != null) {
-					IBinding binding = resolver.getBinding(compilerBinding);
-					if (binding != null)
-						// pass it to requestor
-						astRequestor.acceptBinding(((BindingKey) this.requestedKeys.valueTable[j]).getKey(), binding);
-				}
+				BindingKeyResolver keyResolver = (BindingKeyResolver) keys[j];
+				if (keyResolver == null) continue;
+				Binding compilerBinding = keyResolver.getCompilerBinding();
+				IBinding binding = compilerBinding == null ? null : resolver.getBinding(compilerBinding);
+				// pass it to requestor
+				astRequestor.acceptBinding(((BindingKeyResolver) this.requestedKeys.valueTable[j]).getKey(), binding);
 			}
 		} catch (AbortCompilation e) {
 			this.handleInternalException(e, unit);
@@ -588,6 +720,17 @@
             astRequestor.compilationUnitResolver = null;
 		}
 	}
+
+	private void reportBinding(Object key, ASTRequestor astRequestor, WorkingCopyOwner owner, CompilationUnitDeclaration unit) {
+		BindingKeyResolver keyResolver = (BindingKeyResolver) key;
+		Binding compilerBinding = keyResolver.getCompilerBinding();
+		if (compilerBinding != null) {
+			DefaultBindingResolver resolver = new DefaultBindingResolver(unit.scope, owner, this.bindingTables);
+			IBinding binding = resolver.getBinding(compilerBinding);
+			if (binding != null)
+				astRequestor.acceptBinding(keyResolver.getKey(), binding);
+		}
+	}
 	
 	private CompilationUnitDeclaration resolve(
 			CompilationUnitDeclaration unit,
@@ -714,4 +857,4 @@
 			analyzeCode, 
 			generateCode);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java
index fe984b5..2bfe468 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConditionalExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java
index 6cb4532..82eface 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ConstructorInvocation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -34,7 +34,7 @@
 	
 	/**
 	 * The "typeArguments" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
 		new ChildListPropertyDescriptor(ConstructorInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -58,7 +58,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -87,7 +87,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -98,7 +98,7 @@
 	 * The type arguments (element type: <code>Type</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeArguments = null;
 
@@ -189,18 +189,12 @@
 	/**
 	 * Returns the live ordered list of type arguments of this constructor
 	 * invocation (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type arguments
 	 *    (element type: <code>Type</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeArguments() {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java
index 06700aa..6b9d48f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ContinueStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
index 2156271..ed5123b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index 392ccfa..710b694 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,14 +20,10 @@
 import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
 import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
-import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
-import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
-import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
-import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
 import org.eclipse.jdt.internal.compiler.ast.FieldReference;
-import org.eclipse.jdt.internal.compiler.ast.ImplicitDocTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.ImportReference;
 import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression;
 import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference;
@@ -37,28 +33,31 @@
 import org.eclipse.jdt.internal.compiler.ast.Literal;
 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
-import org.eclipse.jdt.internal.compiler.ast.OperatorExpression;
+import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
 import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
 import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
 import org.eclipse.jdt.internal.compiler.ast.ThisReference;
-import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
 import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 
 /**
  * Internal class for resolving bindings using old ASTs.
@@ -96,10 +95,6 @@
 		}
 	
 	}
-	private static final char[][] JAVA_LANG_EXCEPTION = new char[][] {"java".toCharArray(), "lang".toCharArray(), "Exception".toCharArray()};//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
-	
-	private static final char[][] JAVA_LANG_STRINGBUFFER = new char[][] {"java".toCharArray(), "lang".toCharArray(), "StringBuffer".toCharArray()}; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
-	
 	/**
 	 * This map is used to retrieve the corresponding block scope for a ast node
 	 */
@@ -159,6 +154,16 @@
 		if (binding == null) {
 			return null;
 		}
+		if (binding instanceof IMethodBinding) {
+			IMethodBinding methodBinding = (IMethodBinding) binding;
+			return (ASTNode) this.bindingsToAstNodes.get(methodBinding.getMethodDeclaration());
+		} else if (binding instanceof ITypeBinding) {
+			ITypeBinding typeBinding = (ITypeBinding) binding;
+			return (ASTNode) this.bindingsToAstNodes.get(typeBinding.getTypeDeclaration());
+		} else if (binding instanceof IVariableBinding) {
+			IVariableBinding variableBinding = (IVariableBinding) binding;
+			return (ASTNode) this.bindingsToAstNodes.get(variableBinding.getVariableDeclaration());
+		}
 		return (ASTNode) this.bindingsToAstNodes.get(binding);
 	}
 	
@@ -177,10 +182,14 @@
 			case Binding.PACKAGE:
 				return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding);
 			case Binding.TYPE:
+			case Binding.BASE_TYPE:
 			case Binding.GENERIC_TYPE:
 			case Binding.PARAMETERIZED_TYPE:
 			case Binding.RAW_TYPE:
 				return getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+			case Binding.ARRAY_TYPE:
+			case Binding.TYPE_PARAMETER:
+				return new TypeBinding(this, (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
 			case Binding.METHOD:
 				return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding) binding);
 			case Binding.FIELD:
@@ -217,7 +226,7 @@
 					case ProblemReasons.NonStaticReferenceInConstructorInvocation :
 						ReferenceBinding declaringClass = methodBinding.declaringClass;
 						if (declaringClass != null) {
-							org.eclipse.jdt.internal.compiler.lookup.MethodBinding exactBinding = declaringClass.getExactMethod(methodBinding.selector, methodBinding.parameters);
+							org.eclipse.jdt.internal.compiler.lookup.MethodBinding exactBinding = declaringClass.getExactMethod(methodBinding.selector, methodBinding.parameters, null);
 							if (exactBinding != null) {
 								IMethodBinding binding = (IMethodBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
 								if (binding != null) {
@@ -249,6 +258,16 @@
 		this.bindingTables.compilerBindingsToASTBindings.put(packageBinding, binding);
 		return binding;
 	}
+	private int getTypeArguments(ParameterizedQualifiedTypeReference typeReference) {
+		TypeReference[][] typeArguments = typeReference.typeArguments;
+		int value = 0;
+		for (int i = 0, max = typeArguments.length; i < max; i++) {
+			if ((typeArguments[i] != null) || (value != 0)) {
+				value++;
+			}
+		}
+		return value;
+	}
 		
 	/*
 	 * Method declared on BindingResolver.
@@ -342,6 +361,56 @@
 	}
 	
 	/*
+	 * @see BindingResolver#resolveBoxing(Expression)
+	 */
+	boolean resolveBoxing(Expression expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node != null && (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression)) {
+			org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node;
+			return (compilerExpression.implicitConversion & TypeIds.BOXING) != 0;
+		}
+		return false;
+	}
+	
+	/*
+	 * @see BindingResolver#resolveUnboxing(Expression)
+	 */
+	boolean resolveUnboxing(Expression expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node != null && (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression)) {
+			org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node;
+			return (compilerExpression.implicitConversion & TypeIds.UNBOXING) != 0;
+		}
+		return false;
+	}
+	
+	/*
+	 * @see BindingResolver#resolveConstantExpressionValue(Expression)
+	 */
+	Object resolveConstantExpressionValue(Expression expression) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+		if (node != null && (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression)) {
+			org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node;
+			Constant constant = compilerExpression.constant;
+			if (constant != null && constant != Constant.NotAConstant) {
+				switch (constant.typeID()) {
+					case TypeIds.T_int : return new Integer(constant.intValue());
+					case TypeIds.T_byte : return new Byte(constant.byteValue());
+					case TypeIds.T_short : return new Short(constant.shortValue());
+					case TypeIds.T_char : return new Character(constant.charValue());
+					case TypeIds.T_float : return new Float(constant.floatValue());
+					case TypeIds.T_double : return new Double(constant.doubleValue());
+					case TypeIds.T_boolean : return constant.booleanValue() ? Boolean.TRUE : Boolean.FALSE;
+					case TypeIds.T_long : return new Long(constant.longValue());
+					case TypeIds.T_JavaLangString : return constant.stringValue();
+				}
+				return null;
+			}
+		}
+		return null;
+	}
+	
+	/*
 	 * @see BindingResolver#resolveConstructor(ClassInstanceCreation)
 	 */
 	synchronized IMethodBinding resolveConstructor(ClassInstanceCreation expression) {
@@ -367,6 +436,21 @@
 		return null;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.BindingResolver#resolveConstructor(org.eclipse.jdt.core.dom.EnumConstantDeclaration)
+	 */
+	IMethodBinding resolveConstructor(EnumConstantDeclaration enumConstantDeclaration) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(enumConstantDeclaration);
+		if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node; 
+			if (fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT && fieldDeclaration.initialization != null) {
+				AllocationExpression allocationExpression = (AllocationExpression) fieldDeclaration.initialization;
+				return this.getMethodBinding(allocationExpression.binding);
+			}
+		}
+		return null;
+	}
+
 	/*
 	 * @see BindingResolver#resolveConstructor(SuperConstructorInvocation)
 	 */
@@ -382,154 +466,79 @@
 	 * Method declared on BindingResolver.
 	 */
 	synchronized ITypeBinding resolveExpressionType(Expression expression) {
-		if (expression instanceof ClassInstanceCreation) {
-			org.eclipse.jdt.internal.compiler.ast.ASTNode astNode = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
-			if (astNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
-				org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) astNode;
-				if (typeDeclaration != null) {
-					ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
-					if (typeBinding == null) {
-						return null;
+		switch(expression.getNodeType()) {
+			case ASTNode.CLASS_INSTANCE_CREATION : 
+				org.eclipse.jdt.internal.compiler.ast.ASTNode astNode = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression);
+				if (astNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+					// anonymous type case
+					org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) astNode;
+					if (typeDeclaration != null) {
+						ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+						if (typeBinding == null) {
+							return null;
+						}
+						return typeBinding;
 					}
-					return typeBinding;
-				}
-			} else {
-				// should be an AllocationExpression
-				AllocationExpression allocationExpression = (AllocationExpression) astNode;
-				IMethodBinding methodBinding = this.getMethodBinding(allocationExpression.binding);
-				if (methodBinding == null) {
-					return null;
 				} else {
-					return methodBinding.getDeclaringClass();
+					// should be an AllocationExpression
+					AllocationExpression allocationExpression = (AllocationExpression) astNode;
+					return this.getTypeBinding(allocationExpression.resolvedType);
 				}
-			}
-		} else if (expression instanceof Name) {
-			IBinding binding = this.resolveName((Name) expression);
-			if (binding == null) {
 				return null;
-			}
-			switch(binding.getKind()) {
-				case IBinding.TYPE :
-					return (ITypeBinding) binding;
-				case IBinding.VARIABLE :
-					return ((IVariableBinding) binding).getType();
-				case IBinding.METHOD :
-					return ((IMethodBinding) binding).getReturnType();
-			}
-		} else if (expression instanceof ArrayInitializer) {
-			org.eclipse.jdt.internal.compiler.ast.ArrayInitializer oldAst = (org.eclipse.jdt.internal.compiler.ast.ArrayInitializer) this.newAstToOldAst.get(expression);
-			if (oldAst == null || oldAst.binding == null) {
+			case ASTNode.SIMPLE_NAME :
+			case ASTNode.QUALIFIED_NAME :
+				return this.resolveTypeBindingForName((Name) expression);
+			case ASTNode.ARRAY_INITIALIZER :
+			case ASTNode.ARRAY_CREATION :
+			case ASTNode.ASSIGNMENT :				
+			case ASTNode.POSTFIX_EXPRESSION : 
+			case ASTNode.PREFIX_EXPRESSION :
+			case ASTNode.CAST_EXPRESSION :
+			case ASTNode.TYPE_LITERAL :
+			case ASTNode.INFIX_EXPRESSION :
+			case ASTNode.INSTANCEOF_EXPRESSION :
+			case ASTNode.FIELD_ACCESS :
+			case ASTNode.SUPER_FIELD_ACCESS :
+			case ASTNode.ARRAY_ACCESS :
+			case ASTNode.METHOD_INVOCATION :
+			case ASTNode.SUPER_METHOD_INVOCATION :
+			case ASTNode.CONDITIONAL_EXPRESSION : 
+			case ASTNode.MARKER_ANNOTATION : 
+			case ASTNode.NORMAL_ANNOTATION :
+			case ASTNode.SINGLE_MEMBER_ANNOTATION :
+				org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(expression);
+				if (compilerExpression == null) {
+					return null;
+				}
+				return this.getTypeBinding(compilerExpression.resolvedType);
+			case ASTNode.STRING_LITERAL :
+				return this.getTypeBinding(this.scope.getJavaLangString());
+			case ASTNode.BOOLEAN_LITERAL :
+			case ASTNode.NULL_LITERAL : 
+			case ASTNode.CHARACTER_LITERAL :
+			case ASTNode.NUMBER_LITERAL :
+				Literal literal = (Literal) this.newAstToOldAst.get(expression);
+				return this.getTypeBinding(literal.literalType(null));
+			case ASTNode.THIS_EXPRESSION :
+				ThisReference thisReference = (ThisReference) this.newAstToOldAst.get(expression);
+				BlockScope blockScope = (BlockScope) this.astNodesToBlockScope.get(expression);
+				if (blockScope == null) {
+					return null;
+				}
+				return this.getTypeBinding(thisReference.resolveType(blockScope));
+			case ASTNode.PARENTHESIZED_EXPRESSION :
+				ParenthesizedExpression parenthesizedExpression = (ParenthesizedExpression) expression;
+				return this.resolveExpressionType(parenthesizedExpression.getExpression());
+			case ASTNode.VARIABLE_DECLARATION_EXPRESSION :
+				VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) expression;
+				Type type = variableDeclarationExpression.getType();
+				if (type != null) {
+					return type.resolveBinding();
+				}
 				return null;
-			}
-			return this.getTypeBinding(oldAst.binding);
-		} else if (expression instanceof ArrayCreation) {
-			ArrayAllocationExpression arrayAllocationExpression = (ArrayAllocationExpression) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(arrayAllocationExpression.resolvedType);
-		} else if (expression instanceof Assignment) {
-			Assignment assignment = (Assignment) expression;
-			return this.resolveExpressionType(assignment.getLeftHandSide());
-		} else if (expression instanceof PostfixExpression) {
-			PostfixExpression postFixExpression = (PostfixExpression) expression;
-			return this.resolveExpressionType(postFixExpression.getOperand());
-		} else if (expression instanceof PrefixExpression) {
-			PrefixExpression preFixExpression = (PrefixExpression) expression;
-			return this.resolveExpressionType(preFixExpression.getOperand());
-		} else if (expression instanceof CastExpression) {
-			org.eclipse.jdt.internal.compiler.ast.CastExpression castExpression = (org.eclipse.jdt.internal.compiler.ast.CastExpression) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(castExpression.resolvedType);
-		} else if (expression instanceof StringLiteral) {
-			return this.getTypeBinding(this.scope.getJavaLangString());
-		} else if (expression instanceof TypeLiteral) {
-			ClassLiteralAccess classLiteralAccess = (ClassLiteralAccess) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(classLiteralAccess.resolvedType);
-		} else if (expression instanceof BooleanLiteral) {
-			BooleanLiteral booleanLiteral = (BooleanLiteral) expression;
-			if (booleanLiteral.booleanValue()) {
-				TrueLiteral trueLiteral = (TrueLiteral) this.newAstToOldAst.get(booleanLiteral);
-				return this.getTypeBinding(trueLiteral.literalType(null));
-			} else {
-				FalseLiteral falseLiteral = (FalseLiteral) this.newAstToOldAst.get(booleanLiteral);
-				return this.getTypeBinding(falseLiteral.literalType(null));
-			}
-		} else if (expression instanceof NullLiteral) {
-			org.eclipse.jdt.internal.compiler.ast.NullLiteral nullLiteral = (org.eclipse.jdt.internal.compiler.ast.NullLiteral) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(nullLiteral.literalType(null));
-		} else if (expression instanceof CharacterLiteral) {
-			CharLiteral charLiteral = (CharLiteral) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(charLiteral.literalType(null));
-		} else if (expression instanceof NumberLiteral) {
-			Literal literal = (Literal) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(literal.literalType(null));
-		} else if (expression instanceof InfixExpression) {
-			Object node = this.newAstToOldAst.get(expression);
-			if (node instanceof OperatorExpression) {
-				OperatorExpression operatorExpression = (OperatorExpression) node;
-				return this.getTypeBinding(operatorExpression.resolvedType);
-			} else if (node instanceof StringLiteralConcatenation) {
-				StringLiteralConcatenation stringLiteralConcatenation = (StringLiteralConcatenation) node;
-				return this.getTypeBinding(stringLiteralConcatenation.resolvedType);
-			}
-		} else if (expression instanceof InstanceofExpression) {
-			org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression instanceOfExpression = (org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(instanceOfExpression.resolvedType);
-		} else if (expression instanceof FieldAccess) {
-			FieldReference fieldReference = (FieldReference) this.newAstToOldAst.get(expression);
-			IVariableBinding variableBinding = this.getVariableBinding(fieldReference.binding);
-			if (variableBinding == null) {
+			default: 
 				return null;
-			} else {
-				return variableBinding.getType();
-			}
-		} else if (expression instanceof SuperFieldAccess) {
-			FieldReference fieldReference = (FieldReference) this.newAstToOldAst.get(expression);
-			IVariableBinding variableBinding = this.getVariableBinding(fieldReference.binding);
-			if (variableBinding == null) {
-				return null;
-			} else {
-				return variableBinding.getType();
-			}
-		} else if (expression instanceof ArrayAccess) {
-			ArrayReference arrayReference = (ArrayReference) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(arrayReference.resolvedType);
-		} else if (expression instanceof ThisExpression) {
-			ThisReference thisReference = (ThisReference) this.newAstToOldAst.get(expression);
-			BlockScope blockScope = (BlockScope) this.astNodesToBlockScope.get(expression);
-			if (blockScope == null) {
-				return null;
-			}
-			return this.getTypeBinding(thisReference.resolveType(blockScope));
-		} else if (expression instanceof MethodInvocation
-				|| expression instanceof SuperMethodInvocation) {
-			MessageSend messageSend = (MessageSend)  this.newAstToOldAst.get(expression);
-			IMethodBinding methodBinding = this.getMethodBinding(messageSend.binding);
-			if (methodBinding == null) {
-				return null;
-			} else {
-				return methodBinding.getReturnType();
-			}
-		} else if (expression instanceof ParenthesizedExpression) {
-			ParenthesizedExpression parenthesizedExpression = (ParenthesizedExpression) expression;
-			return this.resolveExpressionType(parenthesizedExpression.getExpression());
-		} else if (expression instanceof ConditionalExpression) {
-			org.eclipse.jdt.internal.compiler.ast.ConditionalExpression conditionalExpression = (org.eclipse.jdt.internal.compiler.ast.ConditionalExpression) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(conditionalExpression.resolvedType);
-		} else if (expression instanceof VariableDeclarationExpression) {
-			VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) expression;
-			Type type = variableDeclarationExpression.getType();
-			if (type != null) {
-				return type.resolveBinding();
-			}
-		} else if (expression instanceof MarkerAnnotation) {
-			org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation markerAnnotation = (org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(markerAnnotation.resolvedType);
-		} else if (expression instanceof NormalAnnotation) {
-			org.eclipse.jdt.internal.compiler.ast.NormalAnnotation normalAnnotation = (org.eclipse.jdt.internal.compiler.ast.NormalAnnotation) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(normalAnnotation.resolvedType);
-		} else if (expression instanceof SingleMemberAnnotation) {
-			org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation singleMemberAnnotation = (org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation) this.newAstToOldAst.get(expression);
-			return this.getTypeBinding(singleMemberAnnotation.resolvedType);
 		}
-		return null;
 	}
 
 	/*
@@ -568,29 +577,52 @@
 			org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(importDeclaration);
 			if (node instanceof ImportReference) {
 				ImportReference importReference = (ImportReference) node;
+				final boolean isStatic = importReference.isStatic();
 				if (importReference.onDemand) {
-					Binding binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length), true, importReference.isStatic());
+					Binding binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length), true, isStatic);
 					if (binding != null) {
-						if ((binding.kind() & Binding.PACKAGE) != 0) {
-							IPackageBinding packageBinding = this.getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding);
-							if (packageBinding == null) {
-								return null;
+						if (isStatic) {
+							if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								return typeBinding == null ? null : typeBinding;								
 							}
-							return packageBinding;
 						} else {
-							// if it is not a package, it has to be a type
-							ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
-							if (typeBinding == null) {
-								return null;
+							if ((binding.kind() & Binding.PACKAGE) != 0) {
+								IPackageBinding packageBinding = this.getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding);
+								if (packageBinding == null) {
+									return null;
+								}
+								return packageBinding;
+							} else {
+								// if it is not a package, it has to be a type
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								if (typeBinding == null) {
+									return null;
+								}
+								return typeBinding;
 							}
-							return typeBinding;
 						}
 					}
 				} else {
-					Binding binding = this.scope.getImport(importReference.tokens, false, importReference.isStatic());
-					if (binding != null && binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
-						ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
-						return typeBinding == null ? null : typeBinding;
+					Binding binding = this.scope.getImport(importReference.tokens, false, isStatic);
+					if (binding != null) {
+						if (isStatic) {
+							if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								return typeBinding == null ? null : typeBinding;								
+							} else if (binding instanceof FieldBinding) {
+								IVariableBinding variableBinding = this.getVariableBinding((FieldBinding) binding);
+								return variableBinding == null ? null : variableBinding;								
+							} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) {
+								// it is a type
+								return this.getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding)binding);						
+							}
+						} else {
+							if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+								ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding);
+								return typeBinding == null ? null : typeBinding;
+							}
+						}
 					}
 				}
 			}
@@ -674,6 +706,208 @@
 		return null;
 	}
 	
+	synchronized ITypeBinding resolveTypeBindingForName(Name name) {
+		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(name);
+		int index = name.index;
+		if (node instanceof QualifiedNameReference) {
+			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) node;
+			final char[][] tokens = qualifiedNameReference.tokens;
+			if (tokens.length == index) {
+				return this.getTypeBinding(qualifiedNameReference.resolvedType);
+			}
+			int indexOfFirstFieldBinding = qualifiedNameReference.indexOfFirstFieldBinding; // one-based
+			if (index < indexOfFirstFieldBinding) {
+				// an extra lookup is required
+				BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
+				Binding binding = null;
+				try {
+					if (internalScope == null) {
+						binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
+					} else {
+						binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
+					}
+				} catch (RuntimeException e) {
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+				}
+				if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+					return null;
+				} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+					// it is a type
+					return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+				}
+			} else if (index == indexOfFirstFieldBinding) {
+				if (qualifiedNameReference.isTypeReference()) {
+					return this.getTypeBinding(qualifiedNameReference.resolvedType);
+				} else {
+					// in this case we want to get the next field declaring's class
+					if (qualifiedNameReference.otherBindings == null) {
+						return null;
+					}
+					FieldBinding fieldBinding = qualifiedNameReference.otherBindings[0];
+					if (fieldBinding == null) return null;
+					org.eclipse.jdt.internal.compiler.lookup.TypeBinding type = fieldBinding.declaringClass;
+					if (type == null) { // array length scenario
+						// use type from first binding (no capture needed for array type)
+						switch (qualifiedNameReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.RestrictiveFlagMASK) {
+							case Binding.FIELD:
+								type = ((FieldBinding) qualifiedNameReference.binding).type;
+								break;
+							case Binding.LOCAL:
+								type = ((LocalVariableBinding) qualifiedNameReference.binding).type;
+								break;
+						}
+					}
+					return this.getTypeBinding(type);
+				}
+			} else {
+				/* This is the case for a name which is part of a qualified name that
+				 * cannot be resolved. See PR 13063.
+				 */
+				if (qualifiedNameReference.otherBindings == null) return null;
+				final int otherBindingsLength = qualifiedNameReference.otherBindings.length;
+				if (otherBindingsLength == (index - indexOfFirstFieldBinding)) {
+					return this.getTypeBinding(qualifiedNameReference.resolvedType);
+				}
+				FieldBinding fieldBinding = qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding];
+				if (fieldBinding == null) return null;
+				org.eclipse.jdt.internal.compiler.lookup.TypeBinding type = fieldBinding.declaringClass;
+				if (type == null) { // array length scenario
+					// use type from previous binding (no capture needed for array type)
+					fieldBinding = qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding - 1];
+					if (fieldBinding == null) return null;
+					type = fieldBinding.type;
+				}
+				return this.getTypeBinding(type);
+			}
+		} else if (node instanceof QualifiedTypeReference) {
+			QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) node;
+			if (qualifiedTypeReference.resolvedType == null) {
+				return null;
+			}
+			if (index == qualifiedTypeReference.tokens.length) {
+				if (!qualifiedTypeReference.resolvedType.isValidBinding() && qualifiedTypeReference instanceof JavadocQualifiedTypeReference) {
+					JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) node;
+					if (typeRef.packageBinding != null) {
+						return null;
+					}
+				}
+				return this.getTypeBinding(qualifiedTypeReference.resolvedType.leafComponentType());
+			} else {
+				if (index >= 0) {
+					BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
+					Binding binding = null;
+					try {
+						if (internalScope == null) {
+							binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
+						} else {
+							binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
+						}
+					} catch (RuntimeException e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
+						return null;
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+						// it is a type
+						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					} else {
+						return null;
+					}
+				}
+			}
+		} else if (node instanceof ImportReference) {
+			ImportReference importReference = (ImportReference) node;
+			int importReferenceLength = importReference.tokens.length;
+			if (index >= 0) {
+				Binding binding = null;
+				if (importReferenceLength == index) {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), importReference.onDemand, importReference.isStatic());
+					} catch (RuntimeException e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				} else {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), true, importReference.isStatic());
+					} catch (RuntimeException e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				}
+				if (binding != null) {
+					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
+						// it is a type
+						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					}
+					return null;
+				}
+			}
+		} else if (node instanceof AbstractMethodDeclaration) {
+			AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node;
+			if (methodDeclaration != null) {
+				IMethodBinding method = this.getMethodBinding(methodDeclaration.binding);
+				if (method == null) return null;
+				return method.getReturnType();
+			}
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+			ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+			if (typeBinding != null) {
+				return typeBinding;
+			}
+		} if (node instanceof SingleNameReference) {
+			SingleNameReference singleNameReference = (SingleNameReference) node;
+			return this.getTypeBinding(singleNameReference.resolvedType);
+		} else if (node instanceof QualifiedSuperReference) {
+			QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) node;
+			return this.getTypeBinding(qualifiedSuperReference.qualification.resolvedType);
+		} else if (node instanceof LocalDeclaration) {
+			IVariableBinding variable = this.getVariableBinding(((LocalDeclaration)node).binding);
+			if (variable == null) return null;
+			return variable.getType();
+		} else if (node instanceof JavadocFieldReference) {
+			JavadocFieldReference fieldRef = (JavadocFieldReference) node;
+			if (fieldRef.methodBinding != null) {
+				return getMethodBinding(fieldRef.methodBinding).getReturnType();
+			}
+			return getTypeBinding(fieldRef.resolvedType);
+		} else if (node instanceof FieldReference) {
+			return getTypeBinding(((FieldReference) node).resolvedType);
+		} else if (node instanceof SingleTypeReference) {
+			SingleTypeReference singleTypeReference = (SingleTypeReference) node;
+			org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = singleTypeReference.resolvedType;
+			if (binding != null) {
+				return this.getTypeBinding(binding.leafComponentType());
+			}
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) {
+			org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node;
+			IVariableBinding field = this.getVariableBinding(fieldDeclaration.binding);
+			if (field == null) return null;
+			return field.getType();
+		} else if (node instanceof MessageSend) {
+			MessageSend messageSend = (MessageSend) node;
+			IMethodBinding method = getMethodBinding(messageSend.binding);
+			if (method == null) return null;
+			return method.getReturnType();
+		} else if (node instanceof AllocationExpression) {
+			AllocationExpression allocation = (AllocationExpression) node;
+			return getTypeBinding(allocation.resolvedType);
+		} else if (node instanceof JavadocImplicitTypeReference) {
+			JavadocImplicitTypeReference implicitRef = (JavadocImplicitTypeReference) node;
+			return getTypeBinding(implicitRef.resolvedType);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) {
+			org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node;
+			return this.getTypeBinding(typeParameter.binding);
+		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.MemberValuePair) {
+			org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair = (org.eclipse.jdt.internal.compiler.ast.MemberValuePair) node;
+			IMethodBinding method = getMethodBinding(memberValuePair.binding);
+			if (method == null) return null;
+			return method.getReturnType();
+		}
+		return null;
+	}	
+	
 	/*
 	 * Method declared on BindingResolver.
 	 */
@@ -683,19 +917,16 @@
 		if (node instanceof QualifiedNameReference) {
 			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) node;
 			final char[][] tokens = qualifiedNameReference.tokens;
-			int qualifiedNameLength = tokens.length;
-			int indexInQualifiedName = qualifiedNameLength - index; // one-based
 			int indexOfFirstFieldBinding = qualifiedNameReference.indexOfFirstFieldBinding; // one-based
-			int otherBindingLength = qualifiedNameLength - indexOfFirstFieldBinding;
-			if (indexInQualifiedName < indexOfFirstFieldBinding) {
-				// a extra lookup is required
+			if (index < indexOfFirstFieldBinding) {
+				// an extra lookup is required
 				BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
 				Binding binding = null;
 				try {
 					if (internalScope == null) {
-						binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, indexInQualifiedName));
+						binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
 					} else {
-						binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, indexInQualifiedName));
+						binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index));
 					}
 				} catch (RuntimeException e) {
 					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
@@ -708,35 +939,33 @@
 					// it is a type
 					return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
 				}
-			} else if (indexInQualifiedName == indexOfFirstFieldBinding) {
+			} else if (index == indexOfFirstFieldBinding) {
 				if (qualifiedNameReference.isTypeReference()) {
-					return this.getTypeBinding((ReferenceBinding)qualifiedNameReference.binding);
+					return this.getTypeBinding(qualifiedNameReference.resolvedType);
 				} else {
 					Binding binding = qualifiedNameReference.binding;
 					if (binding != null) {
 						if (binding.isValidBinding()) {
-							return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding);				
-						} else {
-							if (binding instanceof ProblemFieldBinding) {
-								ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) binding;
-								switch(problemFieldBinding.problemId()) {
-									case ProblemReasons.NotVisible : 
-									case ProblemReasons.NonStaticReferenceInStaticContext :
-										ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
-										if (declaringClass != null) {
-											FieldBinding exactBinding = declaringClass.getField(tokens[tokens.length - 1], true /*resolve*/);
-											if (exactBinding != null) {
-												IVariableBinding variableBinding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
-												if (variableBinding != null) {
-													return variableBinding;
-												}
-												variableBinding = new VariableBinding(this, exactBinding);
-												this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding);
+							return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding);
+						} else  if (binding instanceof ProblemFieldBinding) {
+							ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) binding;
+							switch(problemFieldBinding.problemId()) {
+								case ProblemReasons.NotVisible : 
+								case ProblemReasons.NonStaticReferenceInStaticContext :
+									ReferenceBinding declaringClass = problemFieldBinding.declaringClass;
+									if (declaringClass != null) {
+										FieldBinding exactBinding = declaringClass.getField(tokens[tokens.length - 1], true /*resolve*/);
+										if (exactBinding != null) {
+											IVariableBinding variableBinding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding);
+											if (variableBinding != null) {
 												return variableBinding;
 											}
+											variableBinding = new VariableBinding(this, exactBinding);
+											this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding);
+											return variableBinding;
 										}
-										break;
-								}
+									}
+									break;
 							}
 						}
 					}
@@ -745,10 +974,10 @@
 				/* This is the case for a name which is part of a qualified name that
 				 * cannot be resolved. See PR 13063.
 				 */
-				if (qualifiedNameReference.otherBindings == null || (otherBindingLength - index - 1) < 0) {
+				if (qualifiedNameReference.otherBindings == null || (index - indexOfFirstFieldBinding - 1) < 0) {
 					return null;
 				} else {
-					return this.getVariableBinding(qualifiedNameReference.otherBindings[otherBindingLength - index - 1]);				
+					return this.getVariableBinding(qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding - 1]);				
 				}
 			}
 		} else if (node instanceof QualifiedTypeReference) {
@@ -756,7 +985,7 @@
 			if (qualifiedTypeReference.resolvedType == null) {
 				return null;
 			}
-			if (index == 0) {
+			if (index == qualifiedTypeReference.tokens.length) {
 				if (!qualifiedTypeReference.resolvedType.isValidBinding() && qualifiedTypeReference instanceof JavadocQualifiedTypeReference) {
 					JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) node;
 					if (typeRef.packageBinding != null) {
@@ -765,16 +994,14 @@
 				}
 				return this.getTypeBinding(qualifiedTypeReference.resolvedType.leafComponentType());
 			} else {
-				int qualifiedTypeLength = qualifiedTypeReference.tokens.length;
-				int indexInQualifiedName = qualifiedTypeLength - index; // one-based
-				if (indexInQualifiedName >= 0) {
+				if (index >= 0) {
 					BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name);
 					Binding binding = null;
 					try {
 						if (internalScope == null) {
-							binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, indexInQualifiedName));
+							binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
 						} else {
-							binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, indexInQualifiedName));
+							binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index));
 						}
 					} catch (RuntimeException e) {
 						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
@@ -792,13 +1019,20 @@
 		} else if (node instanceof ImportReference) {
 			ImportReference importReference = (ImportReference) node;
 			int importReferenceLength = importReference.tokens.length;
-			int indexInImportReference = importReferenceLength - index; // one-based
-			if (indexInImportReference >= 0) {
+			if (index >= 0) {
 				Binding binding = null;
-				try {
-					binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, indexInImportReference), true, importReference.isStatic());
-				} catch (RuntimeException e) {
-					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+				if (importReferenceLength == index) {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), importReference.onDemand, importReference.isStatic());
+					} catch (RuntimeException e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
+				} else {
+					try {
+						binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), true, importReference.isStatic());
+					} catch (RuntimeException e) {
+						// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357
+					}
 				}
 				if (binding != null) {
 					if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) {
@@ -806,6 +1040,12 @@
 					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) {
 						// it is a type
 						return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding);
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.FieldBinding) {
+						// it is a type
+						return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.FieldBinding)binding);						
+					} else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) {
+						// it is a type
+						return this.getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding)binding);						
 					} else {
 						return null;
 					}
@@ -841,7 +1081,7 @@
 		} if (node instanceof SingleNameReference) {
 			SingleNameReference singleNameReference = (SingleNameReference) node;
 			if (singleNameReference.isTypeReference()) {
-				return this.getTypeBinding((ReferenceBinding)singleNameReference.binding);
+				return this.getTypeBinding(singleNameReference.resolvedType);
 			} else {
 				// this is a variable or a field
 				Binding binding = singleNameReference.binding;
@@ -909,8 +1149,8 @@
 		} else if (node instanceof AllocationExpression) {
 			AllocationExpression allocation = (AllocationExpression) node;
 			return getMethodBinding(allocation.binding);
-		} else if (node instanceof ImplicitDocTypeReference) {
-			ImplicitDocTypeReference implicitRef = (ImplicitDocTypeReference) node;
+		} else if (node instanceof JavadocImplicitTypeReference) {
+			JavadocImplicitTypeReference implicitRef = (JavadocImplicitTypeReference) node;
 			return getTypeBinding(implicitRef.resolvedType);
 		} else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) {
 			org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node;
@@ -1062,13 +1302,35 @@
 		org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type);
 		org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = null;
 		if (node != null) {
-			if (node instanceof TypeReference) {
+            if (node instanceof ParameterizedQualifiedTypeReference) {
+ 				ParameterizedQualifiedTypeReference typeReference = (ParameterizedQualifiedTypeReference) node;
+ 				org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = typeReference.resolvedType;
+ 				int index;
+ 				if (type.isQualifiedType()) {
+ 					index = ((QualifiedType) type).index;
+ 				} else if (type.isParameterizedType()) {
+ 					index = ((ParameterizedType) type).index;
+ 				} else {
+ 					index = 1;
+ 				}
+ 				final int numberOfTypeArgumentsNotNull = getTypeArguments(typeReference);
+ 				if (index != numberOfTypeArgumentsNotNull) {
+	 				int  i = numberOfTypeArgumentsNotNull;
+	 				while (i != index) {
+	 					typeBinding = typeBinding.enclosingType();
+	 					i --;
+	 				}
+	 				binding = typeBinding;
+ 				} else {
+					binding = typeBinding;
+ 				}
+            } else if (node instanceof TypeReference) {
 				TypeReference typeReference = (TypeReference) node;
 				binding = typeReference.resolvedType;
 			} else if (node instanceof SingleNameReference && ((SingleNameReference)node).isTypeReference()) {
-				binding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) (((SingleNameReference)node).binding);
+				binding = (((SingleNameReference)node).resolvedType);
 			} else if (node instanceof QualifiedNameReference && ((QualifiedNameReference)node).isTypeReference()) {
-				binding = (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) (((QualifiedNameReference)node).binding);
+				binding = (((QualifiedNameReference)node).resolvedType);
 			} else if (node instanceof ArrayAllocationExpression) {
 				binding = ((ArrayAllocationExpression) node).resolvedType;
 			}
@@ -1100,6 +1362,7 @@
 		}
 		return null;
 	}
+
 	/*
 	 * Method declared on BindingResolver.
 	 */
@@ -1201,39 +1464,60 @@
 	 * Method declared on BindingResolver.
 	 */
 	synchronized ITypeBinding resolveWellKnownType(String name) {
-		if (("boolean".equals(name))//$NON-NLS-1$
-			|| ("char".equals(name))//$NON-NLS-1$
-			|| ("byte".equals(name))//$NON-NLS-1$
-			|| ("short".equals(name))//$NON-NLS-1$
-			|| ("int".equals(name))//$NON-NLS-1$
-			|| ("long".equals(name))//$NON-NLS-1$
-			|| ("float".equals(name))//$NON-NLS-1$
-			|| ("double".equals(name))//$NON-NLS-1$
-			|| ("void".equals(name))) {//$NON-NLS-1$
-			return this.getTypeBinding(Scope.getBaseType(name.toCharArray()));
-		} else if ("java.lang.Object".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getJavaLangObject());
-		} else if ("java.lang.String".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getJavaLangString());
-		} else if ("java.lang.StringBuffer".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getType(JAVA_LANG_STRINGBUFFER, 3));
-		} else if ("java.lang.Throwable".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getJavaLangThrowable());
-		} else if ("java.lang.Exception".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getType(JAVA_LANG_EXCEPTION, 3));
-		} else if ("java.lang.RuntimeException".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getJavaLangRuntimeException());
-		} else if ("java.lang.Error".equals(name)) {//$NON-NLS-1$
-			return this.getTypeBinding(this.scope.getJavaLangError());
-		} else if ("java.lang.Class".equals(name)) {//$NON-NLS-1$ 
-			return this.getTypeBinding(this.scope.getJavaLangClass());
-	    } else if ("java.lang.Cloneable".equals(name)) {//$NON-NLS-1$ 
-			return this.getTypeBinding(this.scope.getJavaLangCloneable());
-		} else if ("java.io.Serializable".equals(name)) {//$NON-NLS-1$ 
-			return this.getTypeBinding(this.scope.getJavaIoSerializable());
-		} else {
-			return null;
+		try {
+			if (("boolean".equals(name))//$NON-NLS-1$
+				|| ("char".equals(name))//$NON-NLS-1$
+				|| ("byte".equals(name))//$NON-NLS-1$
+				|| ("short".equals(name))//$NON-NLS-1$
+				|| ("int".equals(name))//$NON-NLS-1$
+				|| ("long".equals(name))//$NON-NLS-1$
+				|| ("float".equals(name))//$NON-NLS-1$
+				|| ("double".equals(name))//$NON-NLS-1$
+				|| ("void".equals(name))) {//$NON-NLS-1$
+				return this.getTypeBinding(Scope.getBaseType(name.toCharArray()));
+			} else if ("java.lang.Object".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getJavaLangObject());
+			} else if ("java.lang.String".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getJavaLangString());
+			} else if ("java.lang.StringBuffer".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_STRINGBUFFER, 3));
+			} else if ("java.lang.Throwable".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getJavaLangThrowable());
+			} else if ("java.lang.Exception".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_EXCEPTION, 3));
+			} else if ("java.lang.RuntimeException".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getJavaLangRuntimeException());
+			} else if ("java.lang.Error".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getJavaLangError());
+			} else if ("java.lang.Class".equals(name)) {//$NON-NLS-1$ 
+				return this.getTypeBinding(this.scope.getJavaLangClass());
+			} else if ("java.lang.Cloneable".equals(name)) {//$NON-NLS-1$ 
+				return this.getTypeBinding(this.scope.getJavaLangCloneable());
+			} else if ("java.io.Serializable".equals(name)) {//$NON-NLS-1$ 
+				return this.getTypeBinding(this.scope.getJavaIoSerializable());
+			} else if ("java.lang.Boolean".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_BOOLEAN, 3));
+			} else if ("java.lang.Byte".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_BYTE, 3));
+			} else if ("java.lang.Character".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_CHARACTER, 3));
+			} else if ("java.lang.Double".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_DOUBLE, 3));
+			} else if ("java.lang.Float".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_FLOAT, 3));
+			} else if ("java.lang.Integer".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_INTEGER, 3));
+			} else if ("java.lang.Long".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_LONG, 3));
+			} else if ("java.lang.Short".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_SHORT, 3));
+			} else if ("java.lang.Void".equals(name)) {//$NON-NLS-1$
+				return this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_VOID, 3));
+			}
+		} catch (AbortCompilation e) {
+			// ignore missing types
 		}
+		return null;
 	}
 	
 	/*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
index 49a9edf..0b01282 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java
index 18f5739..21f0301 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DoStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
index fba9d08..2b57e89 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -55,14 +55,17 @@
 		// Init
 		this.source = this.scanner.source;
 		this.lineEnds = this.scanner.lineEnds;
-		this.docComment = this.ast.newJavadoc();
+		this.docComment = new Javadoc(this.ast);
 		
 		// Parse
 		if (this.checkDocComment) {
-			commentParse(start, start+length-1);
+			this.javadocStart = start;
+			this.javadocEnd = start+length-1;
+			this.firstTagPosition = this.javadocStart;
+			commentParse();
 		}
 		this.docComment.setSourceRange(start, length);
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			setComment(start, length);  // backward compatibility
 		}
 		return this.docComment;
@@ -88,7 +91,7 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createArgumentReference(char[], java.lang.Object, int)
 	 */
-	protected Object createArgumentReference(char[] name, int dim, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
+	protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException {
 		try {
 			MethodRefParameter argument = this.ast.newMethodRefParameter();
 			ASTNode node = (ASTNode) typeRef;
@@ -97,7 +100,8 @@
 			if (dim > 0) argEnd = (int) dimPositions[dim-1];
 			if (argNamePos >= 0) argEnd = (int) argNamePos;
 			if (name.length != 0) {
-				SimpleName argName = this.ast.newSimpleName(new String(name));
+				final SimpleName argName = new SimpleName(this.ast);
+				argName.internalSetIdentifier(new String(name));
 				argument.setName(argName);
 				int argNameStart = (int) (argNamePos >>> 32);
 				argName.setSourceRange(argNameStart, argEnd-argNameStart+1);
@@ -114,7 +118,7 @@
 				argType = this.ast.newSimpleType(argTypeName);
 				argType.setSourceRange(argStart, node.getLength());
 			}
-			if (dim > 0) {
+			if (dim > 0 && !isVarargs) {
 				for (int i=0; i<dim; i++) {
 					argType = this.ast.newArrayType(argType);
 					argType.setSourceRange(argStart, ((int) dimPositions[i])-argStart+1);
@@ -134,7 +138,8 @@
 	protected Object createFieldReference(Object receiver) throws InvalidInputException {
 		try {
 			MemberRef fieldRef = this.ast.newMemberRef();
-			SimpleName fieldName = this.ast.newSimpleName(new String(this.identifierStack[0]));
+			SimpleName fieldName = new SimpleName(this.ast);
+			fieldName.internalSetIdentifier(new String(this.identifierStack[0]));
 			fieldRef.setName(fieldName);
 			int start = (int) (this.identifierPositionStack[0] >>> 32);
 			int end = (int) this.identifierPositionStack[0];
@@ -162,7 +167,8 @@
 		try {
 			// Create method ref
 			MethodRef methodRef = this.ast.newMethodRef();
-			SimpleName methodName = this.ast.newSimpleName(new String(this.identifierStack[0]));
+			SimpleName methodName = new SimpleName(this.ast);
+			methodName.internalSetIdentifier(new String(this.identifierStack[0]));
 			methodRef.setName(methodName);
 			int start = (int) (this.identifierPositionStack[0] >>> 32);
 			int end = (int) this.identifierPositionStack[0];
@@ -266,7 +272,7 @@
 		}
 		ASTNode typeRef = null;
 		if (primitiveToken == -1) {
-			typeRef = this.ast.newName(identifiers);
+			typeRef = this.ast.internalNewName(identifiers);
 		} else {
 			switch (primitiveToken) {
 				case TerminalTokens.TokenNamevoid :
@@ -308,16 +314,20 @@
 		// Update references of each simple name
 		if (size > 1) {
 			Name name = (Name)typeRef;
-			for (int i=this.identifierPtr; i>pos; i--) {
+			int nameIndex = size;
+			for (int i=this.identifierPtr; i>pos; i--, nameIndex--) {
 				int s = (int) (this.identifierPositionStack[i] >>> 32);
 				int e = (int) this.identifierPositionStack[i];
+				name.index = nameIndex;
 				SimpleName simpleName = ((QualifiedName)name).getName();
+				simpleName.index = nameIndex;
 				simpleName.setSourceRange(s, e-s+1);
 				name.setSourceRange(start, e-start+1);
 				name =  ((QualifiedName)name).getQualifier();
 			}
 			int end = (int) this.identifierPositionStack[pos];
 			name.setSourceRange(start, end-start+1);
+			name.index = nameIndex;
 		} else {
 			int end = (int) this.identifierPositionStack[pos];
 			typeRef.setSourceRange(start, end-start+1);
@@ -343,12 +353,10 @@
 		int token = readTokenAndConsume();
 		this.tagSourceStart = this.scanner.getCurrentTokenStartPosition();
 		this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
-		char[] tag = this.scanner.getCurrentIdentifierSource(); // first token is either an identifier or a keyword
 
 		// Try to get tag name other than java identifier
 		// (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660)
 		int tk = token;
-		int le = this.lineEnd;
 		char pc = peekChar();
 		tagNameToken: while (tk != TerminalTokens.TokenNameEOF) {
 			this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
@@ -375,12 +383,11 @@
 			pc = peekChar();
 		}
 		int length = this.tagSourceEnd-this.tagSourceStart+1;
-		tag = new char[length];
+		char[] tag = new char[length];
 		System.arraycopy(this.source, this.tagSourceStart, tag, 0, length);
 		this.index = this.tagSourceEnd+1;
 		this.scanner.currentPosition = this.tagSourceEnd+1;
 		this.tagSourceStart = previousPosition;
-		this.lineEnd = le;
 
 		// Decide which parse to perform depending on tag name
 		this.tagValue = NO_TAG_VALUE;
@@ -404,7 +411,9 @@
 							// Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
 							// was encountered in comment. But it cannot be the case for COMPILER_PARSER
 							// and so is enough as it is only this parser which signals the missing tag warnings...
-							this.inherited = this.astPtr==-1;
+							if (this.astPtr==-1) {
+								this.inheritedPositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd;
+							}
 							this.tagValue = TAG_INHERITDOC_VALUE;
 						} else {
 							this.tagValue = TAG_OTHERS_VALUE;
@@ -550,7 +559,8 @@
 	 */
 	protected boolean pushParamName(boolean isTypeParam) {
 		int idIndex = isTypeParam ? 1 : 0;
-		SimpleName name = this.ast.newSimpleName(new String(this.identifierStack[idIndex]));
+		final SimpleName name = new SimpleName(this.ast);
+		name.internalSetIdentifier(new String(this.identifierStack[idIndex]));
 		int nameStart = (int) (this.identifierPositionStack[idIndex] >>> 32);
 		int nameEnd = (int) (this.identifierPositionStack[idIndex] & 0x00000000FFFFFFFFL);
 		name.setSourceRange(nameStart, nameEnd-nameStart+1);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java
index c078a98..f37c205 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EmptyStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java
index 3ec0fa1..986c97f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnhancedForStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,33 +24,25 @@
  * </pre>
  * The FormalParameter is represented by a <code>SingleVariableDeclaration</code>
  * (without an initializer).
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
- * @since 3.0
+ * 
+ * @since 3.1
  */
 public class EnhancedForStatement extends Statement {
 	
 	/**
 	 * The "parameter" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor PARAMETER_PROPERTY = 
 		new ChildPropertyDescriptor(EnhancedForStatement.class, "parameter", SingleVariableDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "expression" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = 
 		new ChildPropertyDescriptor(EnhancedForStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "body" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor BODY_PROPERTY = 
 		new ChildPropertyDescriptor(EnhancedForStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
@@ -80,7 +72,6 @@
 
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -317,14 +308,6 @@
 		postReplaceChild(oldChild, statement, BODY_PROPERTY);
 	}
 	
-	/**
-	 * @deprecated Use getParameter().resolveBinding() instead.
-	 */
-	// TODO (jeem) remove after 3.1 M4 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=79098
-	public IVariableBinding resolveBinding() {
-		return null;
-	}
-
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java
index f24a2f1..aec9d73 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumConstantDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 package org.eclipse.jdt.core.dom;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -36,14 +35,8 @@
  * arguments and no class body declarations, the source range extends through
  * the last character of the identifier.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class EnumConstantDeclaration extends BodyDeclaration {
 	
@@ -72,16 +65,7 @@
 		new ChildListPropertyDescriptor(EnumConstantDeclaration.class, "arguments", Expression.class, NO_CYCLE_RISK); //$NON-NLS-1$
 	
 	/**
-	 * The "bodyDeclarations" structural property of this node type.
-	 * @deprecated This property has been replaced by ANONYMOUS_CLASS_DECLARATION_PROPERTY.
-	 */
-	// TODO (jeem) - remove this after 3.1 M4
-	public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY = 
-		new ChildListPropertyDescriptor(EnumConstantDeclaration.class, "bodyDeclarations", BodyDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
-	
-	/**
 	 * The "anonymousClassDeclaration" structural property of this node type.
-	 * @since 3.1
 	 */
 	public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY = 
 		new ChildPropertyDescriptor(EnumConstantDeclaration.class, "anonymousClassDeclaration", AnonymousClassDeclaration.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
@@ -100,7 +84,6 @@
 		addProperty(MODIFIERS2_PROPERTY, properyList);
 		addProperty(NAME_PROPERTY, properyList);
 		addProperty(ARGUMENTS_PROPERTY, properyList);
-		addProperty(BODY_DECLARATIONS_PROPERTY, properyList);
 		addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
 		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
 	}
@@ -133,18 +116,8 @@
 		new ASTNode.NodeList(ARGUMENTS_PROPERTY);
 			
 	/**
-	 * The body declarations (element type: <code>BodyDeclaration</code>).
-	 * Defaults to an empty list.
-	 * @deprecated
-	 */
-	// TODO (jeem) - remove this after 3.1 M4
-	private ASTNode.NodeList bodyDeclarations = 
-		new ASTNode.NodeList(BODY_DECLARATIONS_PROPERTY);
-
-	/**
 	 * The optional anonymous class declaration; <code>null</code> for none; 
 	 * defaults to none.
-	 * @since 3.1
 	 */
 	private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null;
 	
@@ -215,9 +188,6 @@
 		if (property == ARGUMENTS_PROPERTY) {
 			return arguments();
 		}
-		if (property == BODY_DECLARATIONS_PROPERTY) {
-			return bodyDeclarations();
-		}
 		// allow default implementation to flag the error
 		return super.internalGetChildListProperty(property);
 	}
@@ -262,8 +232,6 @@
 		result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
 		result.setName((SimpleName) getName().clone(target));
 		result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
-		result.bodyDeclarations().addAll(
-			ASTNode.copySubtrees(target, bodyDeclarations()));
 		result.setAnonymousClassDeclaration(
 				(AnonymousClassDeclaration) ASTNode.copySubtree(target, getAnonymousClassDeclaration()));
 		return result;
@@ -288,7 +256,6 @@
 			acceptChildren(visitor, this.modifiers);
 			acceptChild(visitor, getName());
 			acceptChildren(visitor, this.arguments);
-			acceptChildren(visitor, this.bodyDeclarations);
 			acceptChild(visitor, getAnonymousClassDeclaration());
 		}
 		visitor.endVisit(this);
@@ -347,34 +314,10 @@
 	}
 
 	/**
-	 * Returns the live ordered list of body declarations of this enumeration
-	 * constant declaration. Note that an empty list is equivalent to not
-	 * explicitly specifying any body declarations.
-	 * 
-	 * @return the live list of body declarations
-	 *    (element type: <code>BodyDeclaration</code>)
-	 * @deprecated Use get/setAnonymousClassDeclaration instead.
-	 */
-	// TODO (jeem) - remove this after 3.1 M4
-	public List bodyDeclarations() {
-		return this.bodyDeclarations;
-	}
-
-	/**
-	 * Internal method used to reduce deprecations warnings
-	 * for obsolete bodyDeclarations().
-	 */
-	// TODO (jeem) - remove this after 3.1 M4
-	List obsoleteBodyDeclarations() {
-		return this.bodyDeclarations;
-	}
-	
-	/**
 	 * Returns the anonymous class declaration introduced by this
 	 * enum constant declaration, if it has one.
 	 * 
 	 * @return the anonymous class declaration, or <code>null</code> if none
-	 * @since 3.1
 	 */ 
 	public AnonymousClassDeclaration getAnonymousClassDeclaration() {
 		return this.optionalAnonymousClassDeclaration;
@@ -386,7 +329,6 @@
 	 * 
 	 * @param decl the anonymous class declaration, or <code>null</code> 
 	 *    if none
-	 * @since 3.1
 	 */ 
 	public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) {
 		ASTNode oldChild = this.optionalAnonymousClassDeclaration;
@@ -394,6 +336,21 @@
 		this.optionalAnonymousClassDeclaration = decl;
 		postReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
 	}
+	
+	/**
+	 * Resolves and returns the binding for the constructor invoked by this
+	 * enum constant.
+	 * <p>
+	 * Note that bindings are generally unavailable unless requested when the
+	 * AST is being built.
+	 * </p>
+	 * 
+	 * @return the constructor binding, or <code>null</code> if the binding
+	 *    cannot be resolved
+	 */	
+	public IMethodBinding resolveConstructorBinding() {
+		return this.ast.getBindingResolver().resolveConstructor(this);
+	}
 
 	/**
 	 * Resolves and returns the field binding for this enum constant.
@@ -408,44 +365,12 @@
 	public IVariableBinding resolveVariable() {
 		return this.ast.getBindingResolver().resolveVariable(this);
 	}
-	
-	/* (omit javadoc for this method)
-	 * Method declared on ASTNode.
-	 */
-	void appendDebugString(StringBuffer buffer) {
-		buffer.append("EnumConstantDeclaration[");//$NON-NLS-1$
-		buffer.append(getName().getIdentifier());
-		buffer.append(" ");//$NON-NLS-1$
-		if (!arguments().isEmpty()) {
-			buffer.append("(");//$NON-NLS-1$
-			for (Iterator it = arguments().iterator(); it.hasNext(); ) {
-				Expression e = (Expression) it.next();
-				e.appendDebugString(buffer);
-				if (it.hasNext()) {
-					buffer.append(",");//$NON-NLS-1$
-				}
-			}
-			buffer.append(")");//$NON-NLS-1$
-		}
-		if (getAnonymousClassDeclaration() != null) {
-			buffer.append(" {");//$NON-NLS-1$
-			for (Iterator it = getAnonymousClassDeclaration().bodyDeclarations().iterator(); it.hasNext(); ) {
-				BodyDeclaration d = (BodyDeclaration) it.next();
-				d.appendDebugString(buffer);
-				if (it.hasNext()) {
-					buffer.append(";");//$NON-NLS-1$
-				}
-			}
-			buffer.append("}");//$NON-NLS-1$
-		}
-		buffer.append("]");//$NON-NLS-1$
-	}
 		
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
 	int memSize() {
-		return super.memSize() + 3 * 6;
+		return super.memSize() + 3 * 4;
 	}
 	
 	/* (omit javadoc for this method)
@@ -458,7 +383,6 @@
 			+ this.modifiers.listSize()
 			+ (this.constantName == null ? 0 : getName().treeSize())
 			+ this.arguments.listSize()
-			+ this.bodyDeclarations.listSize()
 			+ (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize());
 	}
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
index 775ba5f..1f650de 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
@@ -1,14 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-
 package org.eclipse.jdt.core.dom;
 
 import java.util.ArrayList;
@@ -38,14 +37,8 @@
  * modifiers or annotations). The source range extends through the last
  * character of the "}" token following the body declarations.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class EnumDeclaration extends AbstractTypeDeclaration {
 	
@@ -75,7 +68,6 @@
 	
 	/**
 	 * The "enumConstants" structural property of this node type.
-	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor ENUM_CONSTANTS_PROPERTY = 
 		new ChildListPropertyDescriptor(EnumDeclaration.class, "enumConstants", EnumConstantDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
@@ -130,7 +122,6 @@
 	 * The enum constant declarations
 	 * (element type: <code>EnumConstantDeclaration</code>).
 	 * Defaults to an empty list.
-	 * @since 3.1
 	 */
 	private ASTNode.NodeList enumConstants = 
 		new ASTNode.NodeList(ENUM_CONSTANTS_PROPERTY);
@@ -308,7 +299,6 @@
 	 * 
 	 * @return the live list of enum constant declarations
 	 *    (element type: {@link EnumConstantDeclaration})
-	 * @since 3.1
 	 */ 
 	public List enumConstants() {
 		return enumConstants;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
index 26b8477..934bb3b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -61,7 +61,39 @@
 	Expression(AST ast) {
 		super(ast);
 	}
-	
+
+	/**
+	 * Resolves and returns the compile-time constant expression value as 
+	 * specified in JLS2 15.28, if this expression has one. Constant expression
+	 * values are unavailable unless bindings are requested when the AST is
+	 * being built. If the type of the value is a primitive type, the result
+	 * is the boxed equivalent (i.e., int returned as an <code>Integer</code>);
+	 * if the type of the value is <code>String</code>, the result is the string
+	 * itself. If the expression does not have a compile-time constant expression
+	 * value, the result is <code>null</code>.
+	 * <p>
+	 * Resolving constant expressions takes into account the value of simple
+	 * and qualified names that refer to constant variables (JLS2 4.12.4).
+	 * </p>
+	 * <p>
+	 * Note 1: enum constants are not considered constant expressions.
+	 * The result is always <code>null</code> for these.
+	 * </p>
+	 * <p>
+	 * Note 2: Compile-time constant expressions cannot denote <code>null</code>.
+	 * So technically {@link NullLiteral} nodes are not constant expressions.
+	 * The result is <code>null</code> for these nonetheless.
+	 * </p>
+	 * 
+	 * @return the constant expression value, or <code>null</code> if this
+	 * expression has no constant expression value or if bindings were not
+	 * requested when the AST was created
+	 * @since 3.1
+	 */
+	public final Object resolveConstantExpressionValue() {
+		return this.ast.getBindingResolver().resolveConstantExpressionValue(this);
+	}
+
 	/**
 	 * Resolves and returns the binding for the type of this expression.
 	 * <p>
@@ -72,8 +104,37 @@
 	 * @return the binding for the type of this expression, or
 	 *    <code>null</code> if the type cannot be resolved
 	 */	
-	public ITypeBinding resolveTypeBinding() {
+	public final ITypeBinding resolveTypeBinding() {
 		return this.ast.getBindingResolver().resolveExpressionType(this);
 	}
+
+	/**
+	 * Returns whether this expression node is the site of a boxing
+	 * conversion (JLS3 5.1.7). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 * 
+	 * @return <code>true</code> if this expression is the site of a
+	 * boxing conversion, or <code>false</code> if either no boxing conversion
+	 * is involved or if bindings were not requested when the AST was created
+	 * @since 3.1
+	 */
+	public final boolean resolveBoxing() {
+		return this.ast.getBindingResolver().resolveBoxing(this);
+	}
+	
+	/**
+	 * Returns whether this expression node is the site of an unboxing
+	 * conversion (JLS3 5.1.8). This information is available only
+	 * when bindings are requested when the AST is being built.
+	 * 
+	 * @return <code>true</code> if this expression is the site of an
+	 * unboxing conversion, or <code>false</code> if either no unboxing
+	 * conversion is involved or if bindings were not requested when the
+	 * AST was created
+	 * @since 3.1
+	 */
+	public final boolean resolveUnboxing() {
+		return this.ast.getBindingResolver().resolveUnboxing(this);
+	}
 }
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java
index 4c9fdbb..49fe271 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ExpressionStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java
index 0663fd5..2c5bb30 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldAccess.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java
index b23523a..f9587f5 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/FieldDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 package org.eclipse.jdt.core.dom;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -49,13 +48,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-    // TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		internalModifiersPropertyFactory(FieldDeclaration.class);
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		internalModifiers2PropertyFactory(FieldDeclaration.class);
@@ -86,7 +84,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -120,7 +118,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -171,7 +169,7 @@
 			if (get) {
 				return getModifiers();
 			} else {
-				setModifiers(value);
+				internalSetModifiers(value);
 				return 0;
 			}
 		}
@@ -253,8 +251,8 @@
 		result.setSourceRange(this.getStartPosition(), this.getLength());
 		result.setJavadoc(
 			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
-		if (this.ast.apiLevel == AST.JLS2) {
-			result.setModifiers(getModifiers());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
 		}
 		if (this.ast.apiLevel >= AST.JLS3) {
 			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
@@ -351,24 +349,6 @@
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
-	void appendDebugString(StringBuffer buffer) {
-		buffer.append("FieldDeclaration["); //$NON-NLS-1$
-		buffer.append("field "); //$NON-NLS-1$
-		getType().appendPrintString(buffer);
-		buffer.append(" "); //$NON-NLS-1$
-		for (Iterator it = fragments().iterator(); it.hasNext(); ) {
-			VariableDeclarationFragment d = (VariableDeclarationFragment) it.next();
-			d.getName().appendPrintString(buffer);
-			if (it.hasNext()) {
-				buffer.append(","); //$NON-NLS-1$
-			}
-		}
-		buffer.append("]"); //$NON-NLS-1$
-	}
-
-	/* (omit javadoc for this method)
-	 * Method declared on ASTNode.
-	 */
 	int memSize() {
 		return super.memSize() + 2 * 4;
 	}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java
index 207b80e..3cd79e1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ForStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java
index ef99040..6e08201 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -127,7 +127,26 @@
 	
 	/**
 	 * Returns the Java element that corresponds to this binding.
-	 * Returns <code>null</code> if this binding has no corresponding Java element.
+	 * Returns <code>null</code> if this binding has no corresponding
+	 * Java element.
+	 * <p>
+	 * For array types, this method returns the Java element that corresponds
+	 * to the array's element type. For raw and parameterized types, this method
+	 * returns the Java element of the erasure.
+	 * </p>
+	 * <p>
+	 * Here are the cases where a <code>null</code> should be expected:
+	 * <ul>
+	 * <li>primitive types, including void</li>
+	 * <li>null type</li>
+	 * <li>wildcard types</li>
+	 * <li>capture types</li>
+	 * <li>the "length" field of an array type</li>
+	 * <li>array types of any of the above</li>
+	 * </ul>
+	 * For all other kind of type, method, variable, and package bindings,
+	 * this method returns non-<code>null</code>.
+	 * </p>
 	 * 
 	 * @return the Java element that corresponds to this binding, 
 	 * 		or <code>null</code> if none
@@ -175,6 +194,7 @@
 	 * the key of the generic type or generic method that declares that
 	 * type variable</li>
 	 * <li>wildcard types - the key of the optional wildcard type bound</li>
+     * <li>capture type bindings - the key of the wildcard captured</li>
 	 * <li>generic type instances - the key of the generic type and the keys
 	 * of the type arguments used to instantiate it, and whether the
 	 * instance is explicit (a parameterized type reference) or
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
index 6ff64a3..c4b4ec1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IDocElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
index 594a0d8..a96b072 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IExtendedModifier.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,7 +18,7 @@
  *   Modifier
  *   Annotation
  * </pre>
- * @since 3.0
+ * @since 3.1
  */
 public interface IExtendedModifier {
 	
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
index a15da21..44b4366 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IMethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -92,6 +92,15 @@
 	 * in declaration order, of this method or constructor. Returns an array of
 	 * length 0 if this method or constructor does not takes any parameters.
 	 * <p>
+	 * Note that the binding for the last parameter type of a vararg method
+	 * declaration like <code>void fun(Foo... args)</code> is always for
+	 * an array type (i.e., <code>Foo[]</code>) reflecting the the way varargs
+	 * get compiled. However, the type binding obtained directly from
+	 * the <code>SingleVariableDeclaration</code> for the vararg parameter
+	 * is always for the type as written; i.e., the type binding for
+	 * <code>Foo</code>.
+	 * </p>
+	 * <p>
 	 * Note: The result does not include synthetic parameters introduced by
 	 * inner class emulation.
 	 * </p>
@@ -129,15 +138,11 @@
 	 * parameters (they instead have non-empty type arguments
 	 * and non-trivial erasure).
 	 * </p>
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
 	 *
 	 * @return the list of binding for the type variables for the type
 	 * parameters of this method, or otherwise the empty list
 	 * @see ITypeBinding#isTypeVariable()
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public ITypeBinding[] getTypeParameters();
 	
@@ -157,10 +162,6 @@
 	 * {@link #isParameterizedMethod()},
 	 * and {@link #isRawMethod()} are mutually exclusive.
 	 * </p>
-	 * <p>
-	 * Note: Support for new language features of the 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
 	 *
 	 * @return <code>true</code> if this method binding represents a 
 	 * declaration of a generic method, and <code>false</code> otherwise
@@ -177,15 +178,11 @@
 	 * {@link #isParameterizedMethod()},
 	 * and {@link #isRawMethod()} are mutually exclusive.
 	 * </p>
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
 	 *
 	 * @return <code>true</code> if this method binding represents a 
 	 * an instance of a generic method corresponding to a parameterized
 	 * method reference, and <code>false</code> otherwise
-	 * @see #getGenericMethod()
+	 * @see #getMethodDeclaration()
 	 * @see #getTypeArguments()
 	 * @since 3.1
 	 */
@@ -201,14 +198,10 @@
 	 * which only occur on the method binding corresponding directly to the
 	 * declaration of a generic method.
 	 * </p> 
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
 	 *
 	 * @return the list of type bindings for the type arguments used to
 	 * instantiate the corrresponding generic method, or otherwise the empty list
-	 * @see #getGenericMethod()
+	 * @see #getMethodDeclaration()
 	 * @see #isParameterizedMethod()
 	 * @see #isRawMethod()
 	 * @since 3.1
@@ -216,49 +209,23 @@
 	public ITypeBinding[] getTypeArguments();
 	
 	/**
-	 * Returns the erasure of this method binding.
-	 * Some bindings correspond to method declarations in the context of
-	 * a particular instance of a generic method. In those cases, this method
-	 * returns the generic method binding from which this method binding
-	 * was instantiated.
-	 * For other type bindings, this method returns the identical type binding.
-	 * Note that the resulting method binding will answer true to
-	 * {@link #isGenericMethod()} iff this method binding would return true
-	 * to either {@link #isGenericMethod()}, {@link #isParameterizedMethod()},
-	 * or {@link #isRawMethod()}.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
+	 * Returns the binding for the method declaration corresponding to this
+	 * method binding. For parameterized methods ({@link #isParameterizedMethod()})
+	 * and raw methods ({@link #isRawMethod()}), this method returns the binding
+	 * for the corresponding generic method. For other method bindings, this
+	 * returns the same binding.
 	 *
-	 * @return the erasure method binding
-	 * @since 3.1
-	 * @deprecated Use {@link #getGenericMethod()} instead.
-	 */
-	// TODO (jeem) - remove before 3.1M5 (bug 80800)
-	public IMethodBinding getErasure();
-	
-	/**
-	 * Returns the generic method corresponding to this method binding.
-	 * Some bindings correspond to method declarations in the context of
-	 * a particular instance of a generic method. In those cases, this method
-	 * returns the generic method binding from which this method binding
-	 * was instantiated.
-	 * For other method bindings, this method returns the identical method binding.
-	 * Note that the resulting method binding will answer true to
-	 * {@link #isGenericMethod()} iff this method binding would return true
-	 * to either {@link #isGenericMethod()}, {@link #isParameterizedMethod()},
-	 * or {@link #isRawMethod()}.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
+	 * <p>Note: The one notable exception is the method <code>Object.getClass()</code>, 
+	 * which is declared to return <code>Class&lt;? extends Object&gt;</code>, but 
+	 * when invoked its return type becomes <code>Class&lt;? extends 
+	 * </code><em>R</em><code>&gt;</code>, where <em>R</em> is the compile type of 
+	 * the receiver of the method invocation.</p>
 	 *
-	 * @return the generic method binding
+	 * @return the method binding
 	 * @since 3.1
 	 */
-	public IMethodBinding getGenericMethod();
-	
+	public IMethodBinding getMethodDeclaration();
+
 	/**
 	 * Returns whether this method binding represents an instance of
 	 * a generic method corresponding to a raw method reference.
@@ -267,21 +234,26 @@
 	 * {@link #isParameterizedMethod()},
 	 * and {@link #isRawMethod()} are mutually exclusive.
 	 * </p>
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
 	 *
 	 * @return <code>true</code> if this method binding represents a 
 	 * an instance of a generic method corresponding to a raw
 	 * method reference, and <code>false</code> otherwise
-	 * @see #getGenericMethod()
+	 * @see #getMethodDeclaration()
 	 * @see #getTypeArguments()
 	 * @since 3.1
 	 */
 	public boolean isRawMethod();
 	
 	/**
+	 * Returns whether this method's signature is a subsignature of the given method as
+	 * specified in section 8.4.2 of <em>The Java Language Specification, Third Edition</em> (JLS3). 
+	 * 
+	 * @return <code>true</code> if this method's signature is a subsignature of the given method
+	 * @since 3.1
+	 */
+	public boolean isSubsignature(IMethodBinding otherMethod);
+	
+	/**
 	 * Returns whether this is a variable arity method.
 	 * <p>
 	 * Note: Variable arity ("varargs") methods were added in JLS3.
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java
index c327583..73f46cd 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IPackageBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
index 737f046..7e0e506 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,19 +32,15 @@
  * possibly with type bounds</li>
  * <li>a wildcard type - represents a wild card used as a type argument in
  * a parameterized type reference</li>
+ * <li>a raw type - represents a legacy non-parameterized reference to
+ * a generic type</li>
+ * <li>a parameterized type - represents an copy of a type declaration
+ * with substitutions for its type parameters</li>
+ * <li>a capture - represents a capture binding</li>
  * </ul>
- * Type bindings usually correspond directly to class or
- * interface declarations found in the source code. However,
- * in some cases of references to a type declared in a generic type,
- * the type binding corresponds to an copy of a type declaration
- * with substitutions for its type parameters.
  * <p>
  * This interface is not intended to be implemented by clients.
  * </p>
- * <p>
- * Note: Support for new language features proposed for the upcoming 1.5
- * release of J2SE is tentative and subject to change.
- * </p>
  * 
  * @see ITypeBinding#getDeclaredTypes()
  * @since 2.0
@@ -68,41 +64,133 @@
 	public String getBinaryName();
 	
 	/**
-	 * Returns whether this type binding represents a primitive type.
-	 * <p>
-	 * There are nine predefined type bindings to represent the eight primitive
-	 * types and <code>void</code>. These have the same names as the primitive
-	 * types that they represent, namely boolean, byte, char, short, int,
-	 * long, float, and double, and void.
-	 * </p>
+	 * Returns the bound of this wildcard type if it has one.
+	 * Returns <code>null</code> if this is not a wildcard type.
 	 * 
-	 * @return <code>true</code> if this type binding is for a primitive type,
-	 *   and <code>false</code> otherwise
+	 * @return the bound of this wildcard type, or <code>null</code> if none
+	 * @see #isWildcardType()
+	 * @see #isUpperbound()
+	 * @since 3.1
 	 */
-	public boolean isPrimitive();
+	public ITypeBinding getBound();
 
 	/**
-	 * Returns whether this type binding represents the null type.
-	 * <p>
-	 * The null type is the type of a <code>NullLiteral</code> node.
-	 * </p>
+	 * Returns a list of bindings representing all the fields declared
+	 * as members of this class, interface, or enum type. These include public, 
+	 * protected, default (package-private) access, and private fields declared
+	 * by the class, but excludes inherited fields. Synthetic fields may or
+	 * may not be included.
+	 * Returns an empty list if the class, interface, or enum declares no fields,
+	 * and for other kinds of type bindings that do not directly have members.
+	 * The resulting bindings are in no particular order.
 	 * 
-	 * @return <code>true</code> if this type binding is for the null type,
-	 *   and <code>false</code> otherwise
+	 * @return the list of bindings for the field members of this type,
+	 *   or the empty list if this type does not have field members
 	 */
-	public boolean isNullType();
+	public IVariableBinding[] getDeclaredFields();
 	
 	/**
-	 * Returns whether this type binding represents an array type.
-	 *
-	 * @return <code>true</code> if this type binding is for an array type,
-	 *   and <code>false</code> otherwise
-	 * @see #getElementType()
-	 * @see #getDimensions()
+	 * Returns a list of method bindings representing all the methods and 
+	 * constructors declared for this class, interface, enum, or annotation
+	 * type. These include public, protected, default (package-private) access,
+	 * and private methods Synthetic methods and constructors may or may not be
+	 * included. Returns an empty list if the class, interface, or enum,
+	 * type declares no methods or constructors, if the annotation type declares
+	 * no members, or if this type binding represents some other kind of type
+	 * binding. The resulting bindings are in no particular order.
+	 * 
+	 * @return the list of method bindings for the methods and constructors
+	 *   declared by this class, interface, enum type, or annotation type, 
+	 *   or the empty list if this type does not declare any methods or constructors
 	 */
-	public boolean isArray();
+	public IMethodBinding[] getDeclaredMethods();
 	
 	/**
+	 * Returns the declared modifiers for this class or interface binding
+	 * as specified in the original source declaration of the class or 
+	 * interface. The result may not correspond to the modifiers in the compiled
+	 * binary, since the compiler may change them (in particular, for inner 
+	 * class emulation). The <code>getModifiers</code> method should be used if
+	 * the compiled modifiers are needed. Returns -1 if this type does not 
+	 * represent a class or interface.
+	 *
+	 * @return the bit-wise or of <code>Modifier</code> constants
+	 * @see #getModifiers()
+	 * @see Modifier
+	 */
+	public int getDeclaredModifiers();
+	
+	/**
+	 * Returns a list of type bindings representing all the types declared as
+	 * members of this class, interface, or enum type. 
+	 * These include public, protected, default (package-private) access,
+	 * and private classes, interfaces, enum types, and annotation types
+	 * declared by the type, but excludes inherited types. Returns an empty
+	 * list if the type declares no type members, or if this type
+	 * binding represents an array type, a primitive type, a type variable,
+	 * a wildcard type, a capture, or the null type.
+	 * The resulting bindings are in no particular order.
+	 * 
+	 * @return the list of type bindings for the member types of this type,
+	 *   or the empty list if this type does not have member types
+	 */
+	public ITypeBinding[] getDeclaredTypes();
+	
+	/**
+	 * Returns the type binding representing the class, interface, or enum
+	 * that declares this binding.
+	 * <p>
+	 * The declaring class of a member class, interface, enum, annotation
+	 * type is the class, interface, or enum type of which it is a member.
+	 * The declaring class of a local class or interface (including anonymous
+	 * classes) is the innermost class or interface containing the expression
+	 * or statement in which this type is declared.
+	 * </p>
+	 * <p>The declaring class of a type variable is the class in which the type variable
+	 * is declared if it is declared on a type. It returns <code>null</code> otherwise.
+	 * </p>
+	 * <p>Array types, primitive types, the null type, top-level types,
+	 * wildcard types, and capture bindings have no declaring class.
+	 * </p>
+	 * 
+	 * @return the binding of the type that declares this type, or
+	 * <code>null</code> if none
+	 */
+	public ITypeBinding getDeclaringClass();
+	
+	/**
+	 * Returns the method binding representing the method that declares this binding
+	 * of a local type or type variable.
+	 * <p>
+	 * The declaring method of a local class or interface (including anonymous
+	 * classes) is the innermost method containing the expression or statement in
+	 * which this type is declared. Returns <code>null</code> if the type
+	 * is declared in an initializer.
+	 * </p>
+	 * <p>
+	 * The declaring method of a type variable is the method in which the type
+	 * variable is declared if it is declared on a method. It
+	 * returns <code>null</code> otherwise.
+	 * </p>
+	 * <p>Array types, primitive types, the null type, top-level types,
+	 * wildcard types, and capture bindings have no declaring method.
+	 * </p>
+	 * 
+	 * @return the binding of the method that declares this type, or
+	 * <code>null</code> if none
+	 */
+	public IMethodBinding getDeclaringMethod();
+
+	/**
+	 * Returns the dimensionality of this array type, or <code>0</code> if this
+	 * is not an array type binding.
+	 *
+	 * @return the number of dimension of this array type binding, or 
+	 *   <code>0</code> if this is not an array type
+	 */
+	public int getDimensions();
+
+	/**
 	 * Returns the binding representing the element type of this array type,
 	 * or <code>null</code> if this is not an array type binding. The element
 	 * type of an array is never itself an array type.
@@ -113,343 +201,77 @@
 	public ITypeBinding getElementType();
 	
 	/**
-	 * Returns the dimensionality of this array type, or <code>0</code> if this
-	 * is not an array type binding.
-	 *
-	 * @return the number of dimension of this array type binding, or 
-	 *   <code>0</code> if this is not an array type
-	 */
-	public int getDimensions();
-	
-	/**
-	 * Returns whether this type is assigment compatible with the given type,
-	 * as specified in section 5.2 of <em>The Java Language 
-	 * Specification, Second Edition</em> (JLS2).
-	 * 
-	 * @param type the type to check compatibility against
-	 * @return <code>true</code> if this type is assigment compatible with the
-	 * given type, and <code>false</code> otherwise
-	 * @since 3.1
-	 */
-	public boolean isAssignmentCompatible(ITypeBinding type);
-	
-	/**
-	 * Returns whether this type is cast compatible with the given type,
-	 * as specified in section 5.5 of <em>The Java Language 
-	 * Specification, Second Edition</em> (JLS2).
-	 * 
-	 * @param type the type to check compatibility against
-	 * @return <code>true</code> if this type is cast compatible with the
-	 * given type, and <code>false</code> otherwise
-	 * @since 3.1
-	 */
-	public boolean isCastCompatible(ITypeBinding type);
-
-	/**
-	 * Returns whether this type binding represents a class type.
-	 *
-	 * @return <code>true</code> if this object represents a class,
-	 *    and <code>false</code> otherwise
-	 */
-	public boolean isClass();
-	
-	/**
-	 * Returns whether this type binding represents an interface type.
-	 *
-	 * @return <code>true</code> if this object represents an interface,
-	 *    and <code>false</code> otherwise
-	 */
-	public boolean isInterface();
-	
-	/**
-	 * Returns whether this type binding represents an enum type.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this object represents an enum type,
-	 *    and <code>false</code> otherwise
-	 * @since 3.0
-	 */
-	public boolean isEnum();
-	
-	/**
-	 * Returns whether this type binding represents an annotation type.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this object represents an annotation type,
-	 *    and <code>false</code> otherwise
-	 * @since 3.0
-	 */
-	public boolean isAnnotation();
-	
-	/**
-	 * Returns the type parameters of this class or interface type binding.
-	 * <p>
-	 * Note that type parameters only occur on the binding of the
-	 * declaring generic class or interface; e.g., <code>Collection&lt;T&gt;</code>.
-	 * Type bindings corresponding to a raw or parameterized reference to a generic
-	 * type do not carry type parameters (they instead have non-empty type arguments
-	 * and non-trivial erasure).
-	 * </p> 
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return the list of binding for the type variables for the type
-	 * parameters of this type, or otherwise the empty list
-	 * @see #isTypeVariable()
-	 * @since 3.0
-	 */
-	// TODO (jeem) - clarify whether binding for a generic type instance carries a copy of the generic type's type parameters as well as type arguments
-	public ITypeBinding[] getTypeParameters();
-	
-	/**
-	 * Returns whether this type binding represents a declaration of
-	 * a generic class or interface.
-	 * <p>
-	 * Note that type parameters only occur on the binding of the
-	 * declaring generic class or interface; e.g., <code>Collection&lt;T&gt;</code>.
-	 * Type bindings corresponding to a raw or parameterized reference to a generic
-	 * type do not carry type parameters (they instead have non-empty type arguments
-	 * and non-trivial erasure).
-	 * This method is fully equivalent to <code>getTypeParameters().length &gt; 0)</code>.
-	 * </p>
-	 * <p>
-	 * Note that {@link #isGenericType()},
-	 * {@link #isParameterizedType()},
-	 * and {@link #isRawType()} are mutually exclusive.
-	 * </p>
-	 * <p>
-	 * Note: Support for new language features of the 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding represents a 
-	 * declaration of a generic class or interface, and <code>false</code> otherwise
-	 * @see #getTypeParameters()
-	 * @since 3.1
-	 */
-	public boolean isGenericType();
-	
-	/**
-	 * Returns whether this type binding represents a type variable.
-	 * Type variables bindings carry the type variable's bounds.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 * 
-	 * @return <code>true</code> if this type binding is for a type variable,
-	 *   and <code>false</code> otherwise
-	 * @see #getName()
-	 * @see #getTypeBounds()
-	 * @since 3.0
-	 */
-	public boolean isTypeVariable();
-	
-	/**
-	 * Returns the type bounds of this type variable.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return the list of type bindings for this type variable, or otherwise
-	 * the empty list
-	 * @see #isTypeVariable()
-	 * @since 3.0
-	 */
-	public ITypeBinding[] getTypeBounds();
-	
-	/**
-	 * Returns whether this type binding represents an instance of
-	 * a generic type corresponding to a parameterized type reference.
-	 * <p>
-	 * For example, an AST type like 
-	 * <code>Collection&lt;String&gt;</code> typically resolves to a
-	 * type binding whose type argument is the type binding for the
-	 * class <code>java.lang.String</code> and whose erasure is the type
-	 * binding for the generic type <code>java.util.Collection</code>.
-	 * </p>
-	 * Note that {@link #isGenericType()},
-	 * {@link #isParameterizedType()},
-	 * and {@link #isRawType()} are mutually exclusive.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding represents a 
-	 * an instance of a generic type corresponding to a parameterized
-	 * type reference, and <code>false</code> otherwise
-	 * @see #getTypeArguments()
-	 * @see #getGenericType()
-	 * @since 3.0
-	 */
-	public boolean isParameterizedType();
-	
-	/**
-	 * Returns the type arguments of this generic type instance, or the
-	 * empty list for other type bindings.
-	 * <p>
-	 * Note that type arguments only occur on a type binding that represents
-	 * an instance of a generic type corresponding to a parameterized type
-	 * reference (e.g., <code>Collection&lt;String&gt;</code>) or to a raw
-	 * type reference (e.g., <code>Collection</code>) to a generic type.
-	 * Do not confuse these with type parameters which only occur on the
-	 * type binding corresponding directly to the declaration of the 
-	 * generic class or interface (e.g., <code>Collection&lt;T&gt;</code>).
-	 * </p> 
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return the list of type bindings for the type arguments used to
-	 * instantiate the corrresponding generic type, or otherwise the empty list
-	 * @see #getGenericType()
-	 * @see #isGenericType()
-	 * @see #isParameterizedType()
-	 * @see #isRawType()
-	 * @since 3.0
-	 */
-	public ITypeBinding[] getTypeArguments();
-	
-	/**
 	 * Returns the erasure of this type binding.
-	 * In the presense of generic types, some bindings correspond to
-	 * types declarations in the context of a particular instance of
-	 * the generic type. In those cases, this method returns
-	 * the generic type binding from which this type binding
-	 * was instantiated. For other type bindings, this method returns
-	 * the identical type binding.
-	 * Note that the resulting type binding will answer true to
-	 * {@link #isGenericType()} iff this type binding would return true
-	 * to either {@link #isGenericType()}, {@link #isParameterizedType()},
-	 * or {@link #isRawType()}.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
+	 * <ul>
+	 * <li>For parameterized types ({@link #isParameterizedType()})
+	 * - returns the binding for the corresponding generic type.</li>
+	 * <li>For raw types ({@link #isRawType()})
+	 * - returns the binding for the corresponding generic type.</li>
+	 * <li>For wildcard types ({@link #isWildcardType()})
+	 * - returns the binding for the upper bound if it has one and
+	 * java.lang.Object in other cases.</li>
+	 * <li>For type variables ({@link #isTypeVariable()})
+	 * - returns the binding for the erasure of the leftmost bound
+	 * if it has bounds and java.lang.Object if it does not.</li>
+	 * <li>For captures ({@link #isCapture()})
+	 * - returns the binding for the erasure of the leftmost bound
+	 * if it has bounds and java.lang.Object if it does not.</li>	 
+	 * <li>For all other type bindings - returns the identical binding.</li>
+	 * </ul>
 	 *
 	 * @return the erasure type binding
-	 * @since 3.0
-	 * @deprecated Use {@link #getGenericType()} instead.
+	 * @since 3.1
 	 */
-	// TODO (jeem) - remove before 3.1M5 (bug 80800)
 	public ITypeBinding getErasure();
 	
 	/**
-	 * Returns the generic type corresponding to this type binding.
-	 * In the presense of generic types, some bindings correspond to
-	 * types declarations in the context of a particular instance of
-	 * the generic type. In those cases, this method returns
-	 * the generic type binding from which this type binding
-	 * was instantiated. For other type bindings, this method returns
-	 * the identical type binding.
-	 * Note that the resulting type binding will answer true to
-	 * {@link #isGenericType()} iff this type binding would return true
-	 * to either {@link #isGenericType()}, {@link #isParameterizedType()},
-	 * or {@link #isRawType()}.
+	 * Returns a list of type bindings representing the direct superinterfaces
+	 * of the class, interface, or enum type represented by this type binding. 
 	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
+	 * If this type binding represents a class or enum type, the return value
+	 * is an array containing type bindings representing all interfaces
+	 * directly implemented by this class. The number and order of the interface
+	 * objects in the array corresponds to the number and order of the interface
+	 * names in the <code>implements</code> clause of the original declaration
+	 * of this type.
+	 * </p>
+	 * <p>
+	 * If this type binding represents an interface, the array contains 
+	 * type bindings representing all interfaces directly extended by this
+	 * interface. The number and order of the interface objects in the array 
+	 * corresponds to the number and order of the interface names in the 
+	 * <code>extends</code> clause of the original declaration of this interface. 
+	 * </p>
+	 * <p>
+	 * If the class or enum implements no interfaces, or the interface extends 
+	 * no interfaces, or if this type binding represents an array type, a
+	 * primitive type, the null type, a type variable, an annotation type, 
+	 * a wildcard type, or a capture binding, this method returns an array of
+     * length 0.
 	 * </p>
 	 *
-	 * @return the generic type binding
-	 * @since 3.1
+	 * @return the list of type bindings for the interfaces extended by this
+	 *   class or enum, or interfaces extended by this interface, or otherwise 
+	 *   the empty list
 	 */
-	public ITypeBinding getGenericType();
+	public ITypeBinding[] getInterfaces();
 	
 	/**
-	 * Returns whether this type binding represents an instance of
-	 * a generic type corresponding to a raw type reference.
-	 * <p>
-	 * For example, an AST type like 
-	 * <code>Collection</code> typically resolves to a
-	 * type binding whose type argument is the type binding for
-	 * the class <code>java.lang.Object</code> (the
-	 * default bound for the single type parameter of 
-	 * <code>java.util.Collection</code>) and whose erasure is the
-	 * type binding for the generic type
-	 * <code>java.util.Collection</code>.
-	 * </p>
-	 * <p>
-	 * Note that {@link #isGenericType()},
-	 * {@link #isParameterizedType()},
-	 * and {@link #isRawType()} are mutually exclusive.
-	 * </p>
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding represents a 
-	 * an instance of a generic type corresponding to a raw
-	 * type reference, and <code>false</code> otherwise
-	 * @see #getGenericType()
-	 * @see #getTypeArguments()
-	 * @since 3.0
-	 */
-	public boolean isRawType();
-	
-	/**
-	 * Returns whether this type binding represents a wildcard type. A wildcard
-	 * type occus only as an argument to a parameterized type reference.
-	 * <p>
-	 * For example, a AST type like 
-	 * <code>Collection&lt;? extends Object&gt;</code> typically resolves to a
-	 * parameterized type binding whose type argument is a wildcard type
-	 * with upper type bound <code>java.util.Object/code>.
-	 * </p>
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this object represents a wildcard type,
-	 *    and <code>false</code> otherwise
-	 * @since 3.0
-	 * @see #getBound()
-	 * @see #isUpperbound()
-	 */
-	public boolean isWildcardType();
-	
-	/**
-	 * Returns the bound of this wildcard type if it has one.
-	 * Returns <code>null</code> if this is not a wildcard type.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
+	 * Returns the compiled modifiers for this class, interface, enum,
+	 * or annotation type binding.
+	 * The result may not correspond to the modifiers as declared in the
+	 * original source, since the compiler may change them (in particular, 
+	 * for inner class emulation). The <code>getDeclaredModifiers</code> method
+	 * should be used if the original modifiers are needed. 
+	 * Returns 0 if this type does not represent a class, interface, enum, or annotation
+	 * type.
 	 * 
-	 * @return the bound of this wildcard type, or <code>null</code> if none
-	 * @see #isWildcardType()
-	 * @see #isUpperbound()
-	 * @since 3.0
+	 * @return the compiled modifiers for this type binding or 0
+	 * if this type does not represent a class, interface, enum, or annotation
+	 * type
+	 * @see #getDeclaredModifiers()
 	 */
-	public ITypeBinding getBound();
-	
-	/**
-	 * Returns whether this wildcard type is an upper bound
-	 * ("extends") as opposed to a lower bound ("super").
-	 * Note that this property is only relevant for wildcards
-	 * that have a bound.
-	 * <p>
-	 * Note: Support for new language features proposed for the upcoming 1.5
-	 * release of J2SE is tentative and subject to change.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this wildcard type has a bound that is
-	 * an upper bound, and <code>false</code> in all other cases
-	 * @see #isWildcardType()
-	 * @see #getBound()
-	 * @since 3.0
-	 */
-	public boolean isUpperbound();
+	public int getModifiers();
 	
 	/**
 	 * Returns the unqualified name of the type represented by this binding
@@ -488,6 +310,8 @@
 	 * this method) when present.
 	 * Example: <code>"? extends InputStream"</code>.
 	 * </li>
+     * <li>Capture types do not have a name. For these types, 
+     * and array types thereof, this method returns an empty string.</li>
 	 * </ul> 
 	 * 
 	 * @return the unqualified name of the type represented by this binding,
@@ -495,272 +319,18 @@
 	 * @see #getQualifiedName()
 	 */
 	public String getName();
-			
+	
 	/**
 	 * Returns the binding for the package in which this type is declared.
 	 * 
 	 * @return the binding for the package in which this class, interface,
 	 * enum, or annotation type is declared, or <code>null</code> if this type
 	 * binding represents a primitive type, an array type, the null type, 
-	 * a type variable, or a wildcard type.
+	 * a type variable, a wildcard type, or a capture binding.
 	 */
 	public IPackageBinding getPackage();
 	
 	/**
-	 * Returns the type binding representing the class, interface, or enum
-	 * that declares this binding.
-	 * <p>
-	 * The declaring class of a member class, interface, enum, annotation
-	 * type is the class, interface, or enum type of which it is a member.
-	 * The declaring class of a local class or interface (including anonymous
-	 * classes) is the innermost class or interface containing the expression
-	 * or statement in which this type is declared. Array types,
-	 * primitive types, the null type, top-level types, type variables,
-	 * and wildcard types have no declaring class.
-	 * </p>
-	 * 
-	 * @return the binding of the type that declares this type, or
-	 * <code>null</code> if none
-	 */
-	public ITypeBinding getDeclaringClass();
-	
-	/**
-	 * Returns the type binding for the superclass of the type represented
-	 * by this class binding.
-	 * <p>
-	 * If this type binding represents any class other than the class
-	 * <code>java.lang.Object</code>, then the type binding for the direct
-	 * superclass of this class is returned. If this type binding represents
-	 * the class <code>java.lang.Object</code>, then <code>null</code> is
-	 * returned.
-	 * <p>
-	 * Loops that ascend the class hierarchy need a suitable termination test.
-	 * Rather than test the superclass for <code>null</code>, it is more 
-	 * transparent to check whether the class is <code>Object</code>, by 
-	 * comparing whether the class binding is identical to 
-	 * <code>ast.resolveWellKnownType("java.lang.Object")</code>.
-	 * </p>
-	 * <p>
-	 * If this type binding represents an interface, an array type, a
-	 * primitive type, the null type, a type variable, an enum type,
-	 * an annotation type, or a wildcard type, then <code>null</code>
-	 * is returned.
-	 * </p>
-	 *
-	 * @return the superclass of the class represented by this type binding,
-	 *    or <code>null</code> if none
-	 * @see AST#resolveWellKnownType(String)
-	 */
-	public ITypeBinding getSuperclass();
-	
-	/**
-	 * Returns a list of type bindings representing the direct superinterfaces
-	 * of the class, interface, or enum type represented by this type binding. 
-	 * <p>
-	 * If this type binding represents a class or enum type, the return value
-	 * is an array containing type bindings representing all interfaces
-	 * directly implemented by this class. The number and order of the interface
-	 * objects in the array corresponds to the number and order of the interface
-	 * names in the <code>implements</code> clause of the original declaration
-	 * of this type.
-	 * </p>
-	 * <p>
-	 * If this type binding represents an interface, the array contains 
-	 * type bindings representing all interfaces directly extended by this
-	 * interface. The number and order of the interface objects in the array 
-	 * corresponds to the number and order of the interface names in the 
-	 * <code>extends</code> clause of the original declaration of this interface. 
-	 * </p>
-	 * <p>
-	 * If the class or enum implements no interfaces, or the interface extends 
-	 * no interfaces, or if this type binding represents an array type, a
-	 * primitive type, the null type, a type variable, an annotation type, 
-	 * or a wildcard type, this method returns an array of length 0.
-	 * </p>
-	 *
-	 * @return the list of type bindings for the interfaces extended by this
-	 *   class or enum, or interfaces extended by this interface, or otherwise 
-	 *   the empty list
-	 */
-	public ITypeBinding[] getInterfaces();
-		
-	/**
-	 * Returns the compiled modifiers for this class, interface, enum,
-	 * or annotation type binding.
-	 * The result may not correspond to the modifiers as declared in the
-	 * original source, since the compiler may change them (in particular, 
-	 * for inner class emulation). The <code>getDeclaredModifiers</code> method
-	 * should be used if the original modifiers are needed. 
-	 * Returns 0 if this type does not represent a class or interface.
-	 * 
-	 * @return the compiled modifiers for this type binding or 0
-	 * if this type does not represent a class, interface, enum, or annotation
-	 * type
-	 * @see #getDeclaredModifiers()
-	 */
-	public int getModifiers();
-	
-	/**
-	 * Returns the declared modifiers for this class or interface binding
-	 * as specified in the original source declaration of the class or 
-	 * interface. The result may not correspond to the modifiers in the compiled
-	 * binary, since the compiler may change them (in particular, for inner 
-	 * class emulation). The <code>getModifiers</code> method should be used if
-	 * the compiled modifiers are needed. Returns -1 if this type does not 
-	 * represent a class or interface.
-	 *
-	 * @return the bit-wise or of <code>Modifier</code> constants
-	 * @see #getModifiers()
-	 * @see Modifier
-	 */
-	public int getDeclaredModifiers();
-	
-	/**
-	 * Returns whether this type is subtype compatible with the given type,
-	 * as specified in section 4.10 of <em>The Java Language 
-	 * Specification, Third Edition</em> (JLS3).
-	 * 
-	 * @param type the type to check compatibility against
-	 * @return <code>true</code> if this type is subtype compatible with the
-	 * given type, and <code>false</code> otherwise
-	 * @since 3.1
-	 */
-	public boolean isSubTypeCompatible(ITypeBinding type);
-	
-	/**
-	 * Returns whether this type binding represents a top-level class,
-	 * interface, enum, or annotation type.
-	 * <p>
-	 * A top-level type is any type whose declaration does not occur within the
-	 * body of another type declaration. The set of top level types is disjoint
-	 * from the set of nested types.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding is for a top-level class,
-	 *   interface, enum, or annotation type, and <code>false</code> otherwise
-	 */
-	public boolean isTopLevel();
-
-	/**
-	 * Returns whether this type binding represents a nested class, interface,
-	 * enum, or annotation type.
-	 * <p>
-	 * A nested type is any type whose declaration occurs within
-	 * the body of another. The set of nested types is disjoint from the set of
-	 * top-level types. Nested types further subdivide into member types, local
-	 * types, and anonymous types.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding is for a nested class,
-	 *   interface, enum, or annotation type, and <code>false</code> otherwise
-	 */
-	public boolean isNested();
-
-	/**
-	 * Returns whether this type binding represents a member class or
-	 * interface.
-	 * <p>
-	 * A member type is any type declared as a member of
-	 * another type. A member type is a subspecies of nested
-	 * type, and mutually exclusive with local types.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding is for a member class,
-	 *   interface, enum, or annotation type, and <code>false</code> otherwise
-	 */
-	public boolean isMember();
-	
-	/**
-	 * Returns whether this type binding represents a local class.
-	 * <p>
-	 * A local class is any nested class or enum type not declared as a member
-	 * of another class or interface. A local class is a subspecies of nested
-	 * type, and mutually exclusive with member types. Note that anonymous
-	 * classes are a subspecies of local classes.
-	 * </p>
-	 * <p>
-	 * Also note that interfaces and annotation types cannot be local.
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding is for a local class or
-	 * enum type, and <code>false</code> otherwise
-	 */
-	public boolean isLocal();
-	
-	/**
-	 * Returns whether this type binding represents an anonymous class.
-	 * <p>
-	 * An anonymous class is a subspecies of local class, and therefore mutually
-	 * exclusive with member types. Note that anonymous classes have no name 
-	 * (<code>getName</code> returns the empty string).
-	 * </p>
-	 *
-	 * @return <code>true</code> if this type binding is for an anonymous class,
-	 *   and <code>false</code> otherwise
-	 */
-	public boolean isAnonymous();
-
-	/**
-	 * Returns a list of type bindings representing all the types declared as
-	 * members of this class, interface, or enum type. 
-	 * These include public, protected, default (package-private) access,
-	 * and private classes, interfaces, enum types, and annotation types
-	 * declared by the type, but excludes inherited types. Returns an empty
-	 * list if the type declares no type members, or if this type
-	 * binding represents an array type, a primitive type, a type variable,
-	 * a wildcard type, or the null type.
-	 * The resulting bindings are in no particular order.
-	 * 
-	 * @return the list of type bindings for the member types of this type,
-	 *   or the empty list if this type does not have member types
-	 */
-	public ITypeBinding[] getDeclaredTypes();
-	
-	/**
-	 * Returns a list of bindings representing all the fields declared
-	 * as members of this class, interface, or enum type. These include public, 
-	 * protected, default (package-private) access, and private fields declared
-	 * by the class, but excludes inherited fields. Synthetic fields may or
-	 * may not be included.
-	 * Returns an empty list if the class, interface, or enum declares no fields,
-	 * and for other kinds of type bindings that do not directly have members.
-	 * The resulting bindings are in no particular order.
-	 * 
-	 * @return the list of bindings for the field members of this type,
-	 *   or the empty list if this type does not have field members
-	 */
-	public IVariableBinding[] getDeclaredFields();
-	
-	/**
-	 * Returns a list of method bindings representing all the methods and 
-	 * constructors declared for this class, interface, or enum. These include
-	 * public, protected, default (package-private) access, and private methods. 
-	 * Synthetic methods and constructors may or may not be included. Returns
-	 * an empty list if the class, interface, or enum declares no methods or 
-	 * constructors, or if this type binding represents some other kind of type
-	 * bindings. The resulting bindings are in no particular order.
-	 * 
-	 * @return the list of method bindings for the methods and constructors
-	 *   declared by this class, interface, or enum type, or the empty list if
-	 * this type does not declare any methods or constructors
-	 */
-	// TODO (jeem) - should result include bindings for annotation type members?
-	public IMethodBinding[] getDeclaredMethods();
-	
-	/**
-	 * Returns whether this type binding originated in source code.
-	 * Returns <code>false</code> for all primitive types, the null type,
-	 * array types, and for all classes, interfaces, enums, annotation
-	 * types, type variables, parameterized type references,
-	 * raw type references, and wildcard types, whose information came from a
-	 * pre-compiled binary class file.
-	 * 
-	 * @return <code>true</code> if the type is in source code,
-	 *    and <code>false</code> otherwise
-	 */
-	public boolean isFromSource();
-	
-	/**
 	 * Returns the fully qualified name of the type represented by this 
 	 * binding if it has one.
 	 * <ul>
@@ -772,7 +342,13 @@
 	 * <li>For members of top-level types, the fully qualified name is the
 	 * simple name of the type preceded by the fully qualified name of the
 	 * enclosing type (as computed by this method) and a ".".
-	 * Example: <code>"java.io.ObjectInputStream.GetField"</code>.</li>
+	 * Example: <code>"java.io.ObjectInputStream.GetField"</code>.
+	 * If the binding is for a member type that corresponds to a particular instance
+	 * of a generic type arising from a parameterized type reference, the simple
+	 * name of the type is followed by the fully qualified names of the type arguments
+	 * (as computed by this method) surrounded by "&lt;&gt;" and separated by ",".
+	 * Example: <code>"pkg.Outer.Inner&lt;java.lang.String&gt;"</code>.
+	 * </li>
 	 * <li>For primitive types, the fully qualified name is the keyword for
 	 * the primitive type.
 	 * Example: <code>"int"</code>.</li>
@@ -805,6 +381,8 @@
 	 * (as computed by this method) when present.
 	 * Example: <code>"? extends java.io.InputStream"</code>.
 	 * </li>
+    * <li>Capture types do not have a fully qualified name. For these types, 
+    * and array types thereof, this method returns an empty string.</li>
 	 * </ul>
 	 * 
 	 * @return the fully qualified name of the type represented by this 
@@ -813,4 +391,466 @@
 	 * @since 2.1
 	 */
 	public String getQualifiedName();
+	
+	/**
+	 * Returns the type binding for the superclass of the type represented
+	 * by this class binding.
+	 * <p>
+	 * If this type binding represents any class other than the class
+	 * <code>java.lang.Object</code>, then the type binding for the direct
+	 * superclass of this class is returned. If this type binding represents
+	 * the class <code>java.lang.Object</code>, then <code>null</code> is
+	 * returned.
+	 * <p>
+	 * Loops that ascend the class hierarchy need a suitable termination test.
+	 * Rather than test the superclass for <code>null</code>, it is more 
+	 * transparent to check whether the class is <code>Object</code>, by 
+	 * comparing whether the class binding is identical to 
+	 * <code>ast.resolveWellKnownType("java.lang.Object")</code>.
+	 * </p>
+	 * <p>
+	 * If this type binding represents an interface, an array type, a
+	 * primitive type, the null type, a type variable, an enum type,
+	 * an annotation type, a wildcard type, or a capture binding,
+     * then <code>null</code> is returned.
+	 * </p>
+	 *
+	 * @return the superclass of the class represented by this type binding,
+	 *    or <code>null</code> if none
+	 * @see AST#resolveWellKnownType(String)
+	 */
+	public ITypeBinding getSuperclass();
+	
+	/**
+	 * Returns the type arguments of this generic type instance, or the
+	 * empty list for other type bindings.
+	 * <p>
+	 * Note that type arguments only occur on a type binding that represents
+	 * an instance of a generic type corresponding to a parameterized type
+	 * reference (e.g., <code>Collection&lt;String&gt;</code>) or to a raw
+	 * type reference (e.g., <code>Collection</code>) to a generic type.
+	 * Do not confuse these with type parameters which only occur on the
+	 * type binding corresponding directly to the declaration of the 
+	 * generic class or interface (e.g., <code>Collection&lt;T&gt;</code>).
+	 * </p> 
+	 *
+	 * @return the list of type bindings for the type arguments used to
+	 * instantiate the corrresponding generic type, or otherwise the empty list
+	 * @see #getTypeDeclaration()
+	 * @see #isGenericType()
+	 * @see #isParameterizedType()
+	 * @see #isRawType()
+	 * @since 3.1
+	 */
+	public ITypeBinding[] getTypeArguments();
+	
+	/**
+	 * Returns the type bounds of this type variable or capture.
+     * <p>
+     * Note that the first type bound is always a class type. If the type
+     * variable does not explicitly declare a class type bound, the first
+     * type bound will be the binding for <code>java.lang.Object</code>.
+     * </p>
+	 *
+	 * @return the list of type bindings for this type variable or capture,
+     * or otherwise the empty list
+	 * @see #isCapture()
+	 * @see #isTypeVariable()
+	 * @since 3.1
+	 */
+	public ITypeBinding[] getTypeBounds();
+	
+	/**
+	 * Returns the binding for the type declaration corresponding to this type
+	 * binding. For parameterized types ({@link #isParameterizedType()})
+	 * and raw types ({@link #isRawType()}), this method returns the binding
+	 * for the corresponding generic type. For other type bindings, this
+	 * returns the same binding.
+	 *
+	 * @return the type binding
+	 * @since 3.1
+	 */
+	public ITypeBinding getTypeDeclaration();
+	
+	/**
+	 * Returns the type parameters of this class or interface type binding.
+	 * <p>
+	 * Note that type parameters only occur on the binding of the
+	 * declaring generic class or interface; e.g., <code>Collection&lt;T&gt;</code>.
+	 * Type bindings corresponding to a raw or parameterized reference to a generic
+	 * type do not carry type parameters (they instead have non-empty type arguments
+	 * and non-trivial erasure).
+	 * </p> 
+	 *
+	 * @return the list of binding for the type variables for the type
+	 * parameters of this type, or otherwise the empty list
+	 * @see #isTypeVariable()
+	 * @since 3.1
+	 */
+	// TODO (jeem) - clarify whether binding for a generic type instance carries a copy of the generic type's type parameters as well as type arguments
+	public ITypeBinding[] getTypeParameters();
+	
+	/**
+	 * Returns the corresponding wildcard binding of this capture binding.
+     * Returns <code>null</code> if this type bindings does not represent
+     * a capture binding.
+	 * 
+	 * @return the corresponding wildcard binding for a capture
+	 * binding, <code>null</code> otherwise
+	 * @since 3.1
+	 */
+	public ITypeBinding getWildcard();
+	
+	/**
+	 * Returns whether this type binding represents an annotation type.
+	 * <p>
+	 * Note that an annotation type is always an interface.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this object represents an annotation type,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isAnnotation();
+	
+	/**
+	 * Returns whether this type binding represents an anonymous class.
+	 * <p>
+	 * An anonymous class is a subspecies of local class, and therefore mutually
+	 * exclusive with member types. Note that anonymous classes have no name 
+	 * (<code>getName</code> returns the empty string).
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for an anonymous class,
+	 *   and <code>false</code> otherwise
+	 */
+	public boolean isAnonymous();
+	
+	/**
+	 * Returns whether this type binding represents an array type.
+	 *
+	 * @return <code>true</code> if this type binding is for an array type,
+	 *   and <code>false</code> otherwise
+	 * @see #getElementType()
+	 * @see #getDimensions()
+	 */
+	public boolean isArray();
+	
+	/**
+	 * Returns whether this type is assigment compatible with the given type,
+	 * as specified in section 5.2 of <em>The Java Language 
+	 * Specification, Third Edition</em> (JLS3).
+	 * 
+	 * @param type the type to check compatibility against
+	 * @return <code>true</code> if this type is assigment compatible with the
+	 * given type, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isAssignmentCompatible(ITypeBinding type);
+	
+	/**
+	 * Returns whether this type binding represents a capture binding.
+	 * <p>
+	 * Capture bindings result from capture conversion as specified 
+	 * in section 5.1.10 of <em>The Java Language Specification, 
+	 * Third Edition</em> (JLS3). 
+	 * </p>
+	 * <p>
+	 * A capture binding may have upper bounds and a lower bound.
+	 * Upper bounds may be accessed using {@link #getTypeBounds()},
+	 * the lower bound must be accessed indirectly through the associated
+	 * wildcard {@link #getWildcard()} when it is a lower bound wildcard.
+	 * </p>
+	 * <p>
+	 * Note that capture bindings are distinct from type variables
+     * (even though they are often depicted as synthetic type
+     * variables); as such, {@link #isTypeVariable()} answers
+     * <code>false</code> for capture bindings, and 
+     * {@link #isCapture()} answers <code>false</code> for type variables.
+	 * </p>
+     *
+	 * @return <code>true</code> if this type binding is a capture,
+	 *   and <code>false</code> otherwise
+	 * @see #getTypeBounds()
+	 * @see #getWildcard()
+	 * @since 3.1
+	 */
+	public boolean isCapture();
+			
+	/**
+	 * Returns whether this type is cast compatible with the given type,
+	 * as specified in section 5.5 of <em>The Java Language 
+	 * Specification, Third Edition</em> (JLS3).
+	 * 
+	 * @param type the type to check compatibility against
+	 * @return <code>true</code> if this type is cast compatible with the
+	 * given type, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isCastCompatible(ITypeBinding type);
+	
+	/**
+	 * Returns whether this type binding represents a class type.
+	 *
+	 * @return <code>true</code> if this object represents a class,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isClass();
+
+	/**
+	 * Returns whether this type binding represents an enum type.
+	 *
+	 * @return <code>true</code> if this object represents an enum type,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isEnum();
+
+	/**
+	 * Returns whether this type binding originated in source code.
+	 * Returns <code>false</code> for all primitive types, the null type,
+	 * array types, and for all classes, interfaces, enums, annotation
+	 * types, type variables, parameterized type references,
+	 * raw type references, wildcard types, and capture bindings
+     * whose information came from a pre-compiled binary class file.
+	 * 
+	 * @return <code>true</code> if the type is in source code,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isFromSource();
+	
+	/**
+	 * Returns whether this type binding represents a declaration of
+	 * a generic class or interface.
+	 * <p>
+	 * Note that type parameters only occur on the binding of the
+	 * declaring generic class or interface; e.g., <code>Collection&lt;T&gt;</code>.
+	 * Type bindings corresponding to a raw or parameterized reference to a generic
+	 * type do not carry type parameters (they instead have non-empty type arguments
+	 * and non-trivial erasure).
+	 * This method is fully equivalent to <code>getTypeParameters().length &gt; 0)</code>.
+	 * </p>
+	 * <p>
+	 * Note that {@link #isGenericType()},
+	 * {@link #isParameterizedType()},
+	 * and {@link #isRawType()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding represents a 
+	 * declaration of a generic class or interface, and <code>false</code> otherwise
+	 * @see #getTypeParameters()
+	 * @since 3.1
+	 */
+	public boolean isGenericType();
+		
+	/**
+	 * Returns whether this type binding represents an interface type.
+	 * <p>
+	 * Note that an interface can also be an annotation type.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this object represents an interface,
+	 *    and <code>false</code> otherwise
+	 */
+	public boolean isInterface();
+	
+	/**
+	 * Returns whether this type binding represents a local class.
+	 * <p>
+	 * A local class is any nested class or enum type not declared as a member
+	 * of another class or interface. A local class is a subspecies of nested
+	 * type, and mutually exclusive with member types. Note that anonymous
+	 * classes are a subspecies of local classes.
+	 * </p>
+	 * <p>
+	 * Also note that interfaces and annotation types cannot be local.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a local class or
+	 * enum type, and <code>false</code> otherwise
+	 */
+	public boolean isLocal();
+	
+	/**
+	 * Returns whether this type binding represents a member class or
+	 * interface.
+	 * <p>
+	 * A member type is any type declared as a member of
+	 * another type. A member type is a subspecies of nested
+	 * type, and mutually exclusive with local types.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a member class,
+	 *   interface, enum, or annotation type, and <code>false</code> otherwise
+	 */
+	public boolean isMember();
+	
+	/**
+	 * Returns whether this type binding represents a nested class, interface,
+	 * enum, or annotation type.
+	 * <p>
+	 * A nested type is any type whose declaration occurs within
+	 * the body of another. The set of nested types is disjoint from the set of
+	 * top-level types. Nested types further subdivide into member types, local
+	 * types, and anonymous types.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a nested class,
+	 *   interface, enum, or annotation type, and <code>false</code> otherwise
+	 */
+	public boolean isNested();
+
+	/**
+	 * Returns whether this type binding represents the null type.
+	 * <p>
+	 * The null type is the type of a <code>NullLiteral</code> node.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if this type binding is for the null type,
+	 *   and <code>false</code> otherwise
+	 */
+	public boolean isNullType();
+
+	/**
+	 * Returns whether this type binding represents an instance of
+	 * a generic type corresponding to a parameterized type reference.
+	 * <p>
+	 * For example, an AST type like 
+	 * <code>Collection&lt;String&gt;</code> typically resolves to a
+	 * type binding whose type argument is the type binding for the
+	 * class <code>java.lang.String</code> and whose erasure is the type
+	 * binding for the generic type <code>java.util.Collection</code>.
+	 * </p>
+	 * Note that {@link #isGenericType()},
+	 * {@link #isParameterizedType()},
+	 * and {@link #isRawType()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding represents a 
+	 * an instance of a generic type corresponding to a parameterized
+	 * type reference, and <code>false</code> otherwise
+	 * @see #getTypeArguments()
+	 * @see #getTypeDeclaration()
+	 * @since 3.1
+	 */
+	public boolean isParameterizedType();
+	
+	/**
+	 * Returns whether this type binding represents a primitive type.
+	 * <p>
+	 * There are nine predefined type bindings to represent the eight primitive
+	 * types and <code>void</code>. These have the same names as the primitive
+	 * types that they represent, namely boolean, byte, char, short, int,
+	 * long, float, and double, and void.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if this type binding is for a primitive type,
+	 *   and <code>false</code> otherwise
+	 */
+	public boolean isPrimitive();
+	
+	/**
+	 * Returns whether this type binding represents an instance of
+	 * a generic type corresponding to a raw type reference.
+	 * <p>
+	 * For example, an AST type like 
+	 * <code>Collection</code> typically resolves to a
+	 * type binding whose type argument is the type binding for
+	 * the class <code>java.lang.Object</code> (the
+	 * default bound for the single type parameter of 
+	 * <code>java.util.Collection</code>) and whose erasure is the
+	 * type binding for the generic type
+	 * <code>java.util.Collection</code>.
+	 * </p>
+	 * <p>
+	 * Note that {@link #isGenericType()},
+	 * {@link #isParameterizedType()},
+	 * and {@link #isRawType()} are mutually exclusive.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding represents a 
+	 * an instance of a generic type corresponding to a raw
+	 * type reference, and <code>false</code> otherwise
+	 * @see #getTypeDeclaration()
+	 * @see #getTypeArguments()
+	 * @since 3.1
+	 */
+	public boolean isRawType();
+
+	/**
+	 * Returns whether this type is subtype compatible with the given type,
+	 * as specified in section 4.10 of <em>The Java Language 
+	 * Specification, Third Edition</em> (JLS3).
+	 * 
+	 * @param type the type to check compatibility against
+	 * @return <code>true</code> if this type is subtype compatible with the
+	 * given type, and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public boolean isSubTypeCompatible(ITypeBinding type);
+	
+	/**
+	 * Returns whether this type binding represents a top-level class,
+	 * interface, enum, or annotation type.
+	 * <p>
+	 * A top-level type is any type whose declaration does not occur within the
+	 * body of another type declaration. The set of top level types is disjoint
+	 * from the set of nested types.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a top-level class,
+	 *   interface, enum, or annotation type, and <code>false</code> otherwise
+	 */
+	public boolean isTopLevel();
+	
+	/**
+	 * Returns whether this type binding represents a type variable.
+	 * Type variables bindings carry the type variable's bounds.
+     * <p>
+     * Note that type variables are distinct from capture bindings
+     * (even though capture bindings are often depicted as synthetic
+     * type variables); as such, {@link #isTypeVariable()} answers
+     * <code>false</code> for capture bindings, and 
+     * {@link #isCapture()} answers <code>false</code> for type variables.
+     * </p>
+	 *
+	 * @return <code>true</code> if this type binding is for a type variable,
+	 *   and <code>false</code> otherwise
+	 * @see #getName()
+	 * @see #getTypeBounds()
+	 * @since 3.1
+	 */
+	public boolean isTypeVariable();
+	
+	/**
+	 * Returns whether this wildcard type is an upper bound
+	 * ("extends") as opposed to a lower bound ("super").
+	 * Note that this property is only relevant for wildcards
+	 * that have a bound.
+	 *
+	 * @return <code>true</code> if this wildcard type has a bound that is
+	 * an upper bound, and <code>false</code> in all other cases
+	 * @see #isWildcardType()
+	 * @see #getBound()
+	 * @since 3.1
+	 */
+	public boolean isUpperbound();
+	
+	/**
+	 * Returns whether this type binding represents a wildcard type. A wildcard
+	 * type occus only as an argument to a parameterized type reference.
+	 * <p>
+	 * For example, a AST type like 
+	 * <code>Collection&lt;? extends Object&gt;</code> typically resolves to a
+	 * parameterized type binding whose type argument is a wildcard type
+	 * with upper type bound <code>java.util.Object/code>.
+	 * </p>
+	 *
+	 * @return <code>true</code> if this object represents a wildcard type,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 * @see #getBound()
+	 * @see #isUpperbound()
+	 */
+	public boolean isWildcardType();
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java
index e88a0cd..ee20893 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IVariableBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,14 +25,28 @@
 public interface IVariableBinding extends IBinding {
 	
 	/**
-	 * Returns whether this binding is for a field or for a local variable.
+	 * Returns whether this binding is for a field.
+	 * Note that this method returns <code>true</code> for constants,
+	 * including enum constants. This method returns <code>false</code>
+	 * for local variables.
 	 * 
 	 * @return <code>true</code> if this is the binding for a field,
-	 *    and <code>false</code> if this is the binding for a local variable
+	 *    and <code>false</code> otherwise
 	 */ 
 	public boolean isField();
 	
 	/**
+	 * Returns whether this binding is for an enum constant.
+	 * Note that this method returns <code>false</code> for local variables
+	 * and for fields other than enum constants.
+	 * 
+	 * @return <code>true</code> if this is the binding for an enum constant,
+	 *    and <code>false</code> otherwise
+	 * @since 3.1
+	 */ 
+	public boolean isEnumConstant();
+	
+	/**
 	 * Returns the name of the field or local variable declared in this binding.
 	 * The name is always a simple identifier.
 	 * 
@@ -98,7 +112,7 @@
 	 * <code>String</code>, the result is the string itself. If the variable has
 	 * no compile-time computed value, the result is <code>null</code>.
 	 * (Note: compile-time constant expressions cannot denote <code>null</code>;
-	 * JLS2 15.28.)
+	 * JLS2 15.28.). The result is always <code>null</code> for enum constants.
 	 * 
 	 * @return the constant value, or <code>null</code> if none
 	 * @since 3.0
@@ -123,4 +137,18 @@
 	 * @since 3.1
 	 */
 	public IMethodBinding getDeclaringMethod();
+	
+	/**
+	 * Returns the binding for the variable declaration corresponding to this
+	 * variable binding. For a binding for a field declaration in an instance
+	 * of a generic type, this method returns the binding for the corresponding
+	 * field declaration in the generic type. For other variable bindings,
+	 * including all ones for local variables and parameters, this method
+	 * returns the same binding.
+	 *
+	 * @return the variable binding for the originating declaration
+	 * @since 3.1
+	 */
+	public IVariableBinding getVariableDeclaration();
+
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java
index bc4365b..1bcebc4 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IfStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java
index e36f01d..9b677ed 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ImportDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -47,7 +47,7 @@
 	
 	/**
 	 * The "static" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final SimplePropertyDescriptor STATIC_PROPERTY = 
 		new SimplePropertyDescriptor(ImportDeclaration.class, "static", boolean.class, MANDATORY); //$NON-NLS-1$
@@ -64,7 +64,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -95,7 +95,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -116,7 +116,7 @@
 	/**
 	 * Static versus regular; defaults to regular import.
 	 * Added in JLS3; not used in JLS2.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private boolean isStatic = false;
 
@@ -303,18 +303,12 @@
 	
 	/**
 	 * Returns whether this import declaration is a static import (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return <code>true</code> if this is a static import,
 	 *    and <code>false</code> if this is a regular import
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public boolean isStatic() {
 		unsupportedIn2();
@@ -323,18 +317,12 @@
 		
 	/**
 	 * Sets whether this import declaration is a static import (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @param isStatic <code>true</code> if this is a static import,
 	 *    and <code>false</code> if this is a regular import
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public void setStatic(boolean isStatic) {
 		unsupportedIn2();
@@ -344,16 +332,27 @@
 	}
 	
 	/**
-	 * Resolves and returns the binding for the package or type imported by
-	 * this import declaration.
+	 * Resolves and returns the binding for the package, type, field, or
+	 * method named in this import declaration.
+	 * <p>
+	 * The name specified in a non-static single-type import can resolve
+	 * to a type (only). The name specified in a non-static on-demand
+	 * import can itself resolve to either a package or a type.
+	 * For static imports (introduced in JLS3), the name specified in a
+	 * static on-demand import can itself resolve to a type (only).
+	 * The name specified in a static single import can resolve to a
+	 * type, field, or method; in cases where the name could be resolved
+	 * to more than one element with that name (for example, two
+	 * methods both named "max", or a method and a field), this method
+	 * returns one of the plausible bindings.
+	 * </p>
 	 * <p>
 	 * Note that bindings are generally unavailable unless requested when the
 	 * AST is being built.
 	 * </p>
 	 * 
-	 * @return the package binding (for on-demand imports) or type binding
-	 *    (for single-type imports), or <code>null</code> if the binding cannot
-	 *    be resolved
+	 * @return a package, type, field, or method binding, or <code>null</code>
+	 * if the binding cannot be resolved
 	 */	
 	public IBinding resolveBinding() {
 		return this.ast.getBindingResolver().resolveImport(this);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java
index 6a4acb7..b91491c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InfixExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java
index 72de196..8bdbbc2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Initializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -36,13 +36,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-    // TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		internalModifiersPropertyFactory(Initializer.class);
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		internalModifiers2PropertyFactory(Initializer.class);
@@ -66,7 +65,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -98,7 +97,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -140,7 +139,7 @@
 			if (get) {
 				return getModifiers();
 			} else {
-				setModifiers(value);
+				internalSetModifiers(value);
 				return 0;
 			}
 		}
@@ -217,8 +216,8 @@
 	ASTNode clone0(AST target) {
 		Initializer result = new Initializer(target);
 		result.setSourceRange(this.getStartPosition(), this.getLength());
-		if (this.ast.apiLevel == AST.JLS2) {
-			result.setModifiers(getModifiers());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
 		}
 		if (this.ast.apiLevel >= AST.JLS3) {
 			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
index 6f9ccbf..0ab286c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InstanceofExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
index 73c4a45..6b20808 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/InternalASTRewrite.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,6 +20,7 @@
 
 import org.eclipse.jdt.core.dom.SimplePropertyDescriptor;
 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
 import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
 import org.eclipse.jdt.internal.core.dom.rewrite.ListRewriteEvent;
 import org.eclipse.jdt.internal.core.dom.rewrite.NodeInfoStore;
@@ -65,9 +66,23 @@
 	public TextEdit rewriteAST(IDocument document, Map options) {
 		TextEdit result = new MultiTextEdit();
 		
-		CompilationUnit rootNode = getRootNode();
+		final CompilationUnit rootNode = getRootNode();
 		if (rootNode != null) {
-			ASTRewriteAnalyzer visitor = new ASTRewriteAnalyzer(document, rootNode, result, this.eventStore, this.nodeStore, options);
+			TargetSourceRangeComputer xsrComputer = new TargetSourceRangeComputer() {
+				/** 
+				 * This implementation of
+				 * {@link TargetSourceRangeComputer#computeSourceRange(ASTNode)}
+				 * is specialized to work in the case of internal AST rewriting, where the
+				 * original AST has been modified from its original form. This means that
+				 * one cannot trust that the root of the given node is the compilation unit.
+				 */
+				public SourceRange computeSourceRange(ASTNode node) {
+					int extendedStartPosition = rootNode.getExtendedStartPosition(node);
+					int extendedLength = rootNode.getExtendedLength(node);
+					return new SourceRange(extendedStartPosition, extendedLength);
+				}
+			};
+			ASTRewriteAnalyzer visitor = new ASTRewriteAnalyzer(document, result, this.eventStore, this.nodeStore, options, xsrComputer);
 			rootNode.accept(visitor);
 		}
 		return result;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java
index dfb9646..2eb2505 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Javadoc.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,14 +32,14 @@
 	/**
 	 * The "comment" structural property of this node type (JLS2 API only).
 	 * @since 3.0
+	 * @deprecated Replaced by {@link #TAGS_PROPERTY} in the JLS3 API.
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #TAGS_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor COMMENT_PROPERTY = 
 		new SimplePropertyDescriptor(Javadoc.class, "comment", String.class, MANDATORY); //$NON-NLS-1$
 	
 	/**
 	 * The "tags" structural property of this node type.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TAGS_PROPERTY = 
 		new ChildListPropertyDescriptor(Javadoc.class, "tags", TagElement.class, CYCLE_RISK); //$NON-NLS-1$
@@ -57,7 +57,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -85,7 +85,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -178,7 +178,7 @@
 	ASTNode clone0(AST target) {
 		Javadoc result = new Javadoc(target);
 		result.setSourceRange(this.getStartPosition(), this.getLength());
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			result.setComment(getComment());
 		}
 		result.tags().addAll(ASTNode.copySubtrees(target, tags()));
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java
index de40526..52f6d24 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LabeledStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java
index c40b816..c800387 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/LineComment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java
index c8b26e8..bcb9115 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MarkerAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -22,19 +22,13 @@
  *   <b>@</b> TypeName
  * </pre>
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
- * @since 3.0
+ * 
+ * @since 3.1
  */
 public final class MarkerAnnotation extends Annotation {
 
 	/**
 	 * The "typeName" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY = 
 		internalTypeNamePropertyFactory(MarkerAnnotation.class);
@@ -43,7 +37,6 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
 	 */
 	private static final List PROPERTY_DESCRIPTORS;
 	
@@ -61,7 +54,6 @@
 	 * @param apiLevel the API level; one of the AST.JLS* constants
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -84,7 +76,6 @@
 
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
-	 * @since 3.0
 	 */
 	final List internalStructuralPropertiesForType(int apiLevel) {
 		return propertyDescriptors(apiLevel);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java
index 64ffd08..8379ccf 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberRef.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java
index b892e12..887e99c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MemberValuePair.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,27 +24,20 @@
  * Within annotations, only certain kinds of expressions are meaningful,
  * including other annotations.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
+ *
  * @see NormalAnnotation
- * @since 3.0
+ * @since 3.1
  */
 public class MemberValuePair extends ASTNode {
 	
 	/**
 	 * The "name" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor NAME_PROPERTY = 
 		new ChildPropertyDescriptor(MemberValuePair.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "value" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor VALUE_PROPERTY = 
 		new ChildPropertyDescriptor(MemberValuePair.class, "value", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java
index 29705a6..a120076 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Message.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
index 5a42959..7ed6eb1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,8 +24,12 @@
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
 import org.eclipse.jdt.internal.core.Member;
+import org.eclipse.jdt.internal.core.util.Util;
 
 /**
  * Internal implementation of method bindings.
@@ -64,7 +68,15 @@
 	 * @since 3.0
 	 */
 	public boolean isDefaultConstructor() {
-		if (this.binding.declaringClass.isBinaryBinding()) {
+		final ReferenceBinding declaringClassBinding = this.binding.declaringClass;
+		if (declaringClassBinding.isRawType()) {
+			RawTypeBinding rawTypeBinding = (RawTypeBinding) declaringClassBinding;
+			if (rawTypeBinding.type.isBinaryBinding()) {
+				return false;
+			}
+			return (this.binding.modifiers & CompilerModifiers.AccIsDefaultConstructor) != 0;
+		}
+		if (declaringClassBinding.isBinaryBinding()) {
 			return false;
 		}
 		return (this.binding.modifiers & CompilerModifiers.AccIsDefaultConstructor) != 0;
@@ -125,61 +137,6 @@
 	}
 	
 	/*
-	 * Returns the signature of the given type.
-	 */
-	private String getSignature(Type type) {
-		StringBuffer buffer = new StringBuffer();
-		getFullyQualifiedName(type, buffer);
-		return Signature.createTypeSignature(buffer.toString(), false/*not resolved in source*/);
-	}
-	
-	/*
-	 * Appends to the given buffer the fully qualified name (as it appears in the source) of the given type
-	 */
-	private void getFullyQualifiedName(Type type, StringBuffer buffer) {
-		if (type.isArrayType()) {
-			ArrayType arrayType = (ArrayType) type;
-			getFullyQualifiedName(arrayType.getElementType(), buffer);
-			for (int i = 0, length = arrayType.getDimensions(); i < length; i++) {
-				buffer.append('[');
-				buffer.append(']');
-			}
-		} else if (type.isParameterizedType()) {
-			ParameterizedType parameterizedType = (ParameterizedType) type;
-			getFullyQualifiedName(parameterizedType.getType(), buffer);
-			buffer.append('<');
-			Iterator iterator = parameterizedType.typeArguments().iterator();
-			boolean isFirst = true;
-			while (iterator.hasNext()) {
-				if (!isFirst)
-					buffer.append(',');
-				else
-					isFirst = false;
-				Type typeArgument = (Type) iterator.next();
-				getFullyQualifiedName(typeArgument, buffer);
-			}
-			buffer.append('>');
-		} else if (type.isPrimitiveType()) {
-			buffer.append(((PrimitiveType) type).getPrimitiveTypeCode().toString());
-		} else if (type.isQualifiedType()) {
-			buffer.append(((QualifiedType) type).getName().getFullyQualifiedName());
-		} else if (type.isSimpleType()) {
-			buffer.append(((SimpleType) type).getName().getFullyQualifiedName());
-		} else if (type.isWildcardType()) {
-			buffer.append('?');
-			WildcardType wildcardType = (WildcardType) type;
-			Type bound = wildcardType.getBound();
-			if (bound == null) return;
-			if (wildcardType.isUpperBound()) {
-				buffer.append(" extends "); //$NON-NLS-1$
-			} else {
-				buffer.append(" super "); //$NON-NLS-1$
-			}
-			getFullyQualifiedName(bound, buffer);
-		}
-	}
-
-	/*
 	 * @see IMethodBinding#getExceptionTypes()
 	 */
 	public ITypeBinding[] getExceptionTypes() {
@@ -203,29 +160,43 @@
 		IType declaringType = (IType) getDeclaringClass().getJavaElement();
 		if (declaringType == null) return null;
 		if (!(this.resolver instanceof DefaultBindingResolver)) return null;
-		MethodDeclaration methodDeclaration = (MethodDeclaration) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this);
-		if (methodDeclaration != null) {
-			ArrayList parameterSignatures = new ArrayList();
-			Iterator iterator = methodDeclaration.parameters().iterator();
-			while (iterator.hasNext()) {
-				SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
-				Type type = parameter.getType();
-				parameterSignatures.add(getSignature(type));
+		ASTNode node = (ASTNode) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this);
+		if (node != null && declaringType.getParent().getElementType() != IJavaElement.CLASS_FILE) {
+			if (node instanceof MethodDeclaration) {
+				MethodDeclaration methodDeclaration = (MethodDeclaration) node;
+				ArrayList parameterSignatures = new ArrayList();
+				Iterator iterator = methodDeclaration.parameters().iterator();
+				while (iterator.hasNext()) {
+					SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
+					Type type = parameter.getType();
+					String typeSig = Util.getSignature(type);
+					int arrayDim = parameter.getExtraDimensions();
+					if (parameter.isVarargs())
+						arrayDim++;
+					if (arrayDim > 0)
+						typeSig = Signature.createArraySignature(typeSig, arrayDim);
+					parameterSignatures.add(typeSig);
+				}
+				int parameterCount = parameterSignatures.size();
+				String[] parameters = new String[parameterCount];
+				parameterSignatures.toArray(parameters);
+				return declaringType.getMethod(getName(), parameters);
+			} else {
+				// annotation type member declaration
+				AnnotationTypeMemberDeclaration typeMemberDeclaration = (AnnotationTypeMemberDeclaration) node;
+				return declaringType.getMethod(typeMemberDeclaration.getName().getIdentifier(), new String[0]); // annotation type members don't have parameters
 			}
-			int parameterCount = parameterSignatures.size();
-			String[] parameters = new String[parameterCount];
-			parameterSignatures.toArray(parameters);
-			return declaringType.getMethod(getName(), parameters);
 		} else {
-			// case of method not in the created AST
-			String selector = getName();
-			char[] methodSignature = this.binding.genericSignature();
-			if (methodSignature == null)
-				methodSignature = this.binding.signature();
-			methodSignature = CharOperation.replaceOnCopy(methodSignature, '/', '.');
-			char[][] parameterSignatures = Signature.getParameterTypes(methodSignature);
-			String[] parameters = CharOperation.toStrings(parameterSignatures);
-			IMethod result = declaringType.getMethod(selector, parameters);
+			// case of method not in the created AST, or a binary method
+			org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = this.binding.original();
+			String selector = original.isConstructor() ? declaringType.getElementName() : new String(original.selector);
+			TypeBinding[] parameters = original.parameters;
+			int length = parameters == null ? 0 : parameters.length;
+			String[] parameterSignatures = new String[length];
+			for (int i = 0;  i < length; i++) {
+				parameterSignatures[i] = new String(parameters[i].genericTypeSignature()).replace('/', '.');
+			}
+			IMethod result = declaringType.getMethod(selector, parameterSignatures);
 			if (declaringType.isBinary())
 				return result;
 			IMethod[] methods = null;
@@ -390,19 +361,18 @@
 		return (this.binding instanceof ParameterizedGenericMethodBinding)
 			&& ((ParameterizedGenericMethodBinding) this.binding).isRaw;
 	}
+	
+	public boolean isSubsignature(IMethodBinding otherMethod) {
+		org.eclipse.jdt.internal.compiler.lookup.MethodBinding other = ((MethodBinding) otherMethod).binding;
+		if (!CharOperation.equals(this.binding.selector, other.selector))
+			return false;
+		return this.binding.areParameterErasuresEqual(other);
+	}
 
 	/**
-	 * @deprecated Use {@link #getGenericMethod()} instead.
+	 * @see org.eclipse.jdt.core.dom.IMethodBinding#getMethodDeclaration()
 	 */
-	// TODO (jeem) - remove before 3.1M5 (bug 80800)
-	public IMethodBinding getErasure() {
-		return getGenericMethod();
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.core.dom.IMethodBinding#getGenericMethod()
-	 */
-	public IMethodBinding getGenericMethod() {
+	public IMethodBinding getMethodDeclaration() {
 		return this.resolver.getMethodBinding(this.binding.original());
 	}
 	
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
index 0184d15..013d9e9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 package org.eclipse.jdt.core.dom;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -76,13 +75,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-    // TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		internalModifiersPropertyFactory(MethodDeclaration.class);
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		internalModifiers2PropertyFactory(MethodDeclaration.class);
@@ -105,13 +103,12 @@
 	 * The "returnType" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #RETURN_TYPE2_PROPERTY} in the JLS3 API.
 	public static final ChildPropertyDescriptor RETURN_TYPE_PROPERTY = 
 		new ChildPropertyDescriptor(MethodDeclaration.class, "returnType", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "returnType2" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildPropertyDescriptor RETURN_TYPE2_PROPERTY = 
 		new ChildPropertyDescriptor(MethodDeclaration.class, "returnType2", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -125,7 +122,7 @@
 	
 	/**
 	 * The "typeParameters" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY = 
 		new ChildListPropertyDescriptor(MethodDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -163,7 +160,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -206,7 +203,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -243,7 +240,7 @@
 	
 	/**
 	 * Indicated whether the return type has been initialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private boolean returnType2Initialized = false;
 	
@@ -251,7 +248,7 @@
 	 * The type paramters (element type: <code>TypeParameter</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeParameters = null;
 
@@ -314,7 +311,7 @@
 			if (get) {
 				return getModifiers();
 			} else {
-				setModifiers(value);
+				internalSetModifiers(value);
 				return 0;
 			}
 		}
@@ -450,8 +447,8 @@
 		result.setSourceRange(this.getStartPosition(), this.getLength());
 		result.setJavadoc(
 			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
-		if (this.ast.apiLevel == AST.JLS2) {
-			result.setModifiers(getModifiers());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
 			result.setReturnType(
 					(Type) ASTNode.copySubtree(target, getReturnType()));
 		}
@@ -490,7 +487,7 @@
 		if (visitChildren) {
 			// visit children in normal left to right reading order
 			acceptChild(visitor, getJavadoc());
-			if (this.ast.apiLevel == AST.JLS2) {
+			if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 				acceptChild(visitor, getReturnType());
 			} else {
 				acceptChildren(visitor, this.modifiers);
@@ -531,18 +528,12 @@
 	/**
 	 * Returns the live ordered list of type parameters of this method
 	 * declaration (added in JLS3 API). This list is non-empty for parameterized methods.
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type parameters
 	 *    (element type: <code>TypeParameter</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeParameters() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -610,19 +601,13 @@
 	 * Returns whether this method declaration declares a
 	 * variable arity method (added in JLS3 API). The convenience method checks
 	 * whether the last parameter is so marked.
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return <code>true</code> if this is a variable arity method declaration,
 	 *    and <code>false</code> otherwise
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
 	 * @see SingleVariableDeclaration#isVarargs()
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public boolean isVarargs() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -662,10 +647,20 @@
 	 * @return the return type, possibly the void primitive type
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by {@link #getReturnType2()},
+	 * which may return <code>null</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>getReturnType2</code>, which may return <code>null</code>.
 	public Type getReturnType() {
-	    supportedOnlyIn2();
+		return internalGetReturnType();
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final Type internalGetReturnType() {
+		supportedOnlyIn2();
 		if (this.returnType == null) {
 			// lazy init must be thread-safe for readers
 			synchronized (this) {
@@ -696,9 +691,19 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link #setReturnType2(Type)}, which accepts <code>null</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>setReturnType2</code>, which accepts <code>null</code>.
 	public void setReturnType(Type type) {
+		internalSetReturnType(type);
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ void internalSetReturnType(Type type) {
 	    supportedOnlyIn2();
 		if (type == null) {
 			throw new IllegalArgumentException();
@@ -725,7 +730,7 @@
 	 * or <code>null</code> if none
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public Type getReturnType2() {
 	    unsupportedIn2();
@@ -763,7 +768,7 @@
 	 * <li>the node belongs to a different AST</li>
 	 * <li>the node already has a parent</li>
 	 * </ul>
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public void setReturnType2(Type type) {
 	    unsupportedIn2();
@@ -878,25 +883,6 @@
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
-	void appendDebugString(StringBuffer buffer) {
-		buffer.append("MethodDeclaration[");//$NON-NLS-1$
-		buffer.append(isConstructor() ? "constructor " : "method ");//$NON-NLS-2$//$NON-NLS-1$
-		buffer.append(getName().getIdentifier());
-		buffer.append("(");//$NON-NLS-1$
-		for (Iterator it = parameters().iterator(); it.hasNext(); ) {
-			SingleVariableDeclaration d = (SingleVariableDeclaration) it.next();
-			d.getType().appendPrintString(buffer);
-			if (it.hasNext()) {
-				buffer.append(";");//$NON-NLS-1$
-			}
-		}
-		buffer.append(")");//$NON-NLS-1$
-		buffer.append("]");//$NON-NLS-1$
-	}
-
-	/* (omit javadoc for this method)
-	 * Method declared on ASTNode.
-	 */
 	int memSize() {
 		return super.memSize() + 9 * 4;
 	}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java
index 87937be..6ea6d6c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodInvocation.java
@@ -1,14 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-
 package org.eclipse.jdt.core.dom;
 
 import java.util.ArrayList;
@@ -43,7 +42,7 @@
 
 	/**
 	 * The "typeArguments" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
 		new ChildListPropertyDescriptor(MethodInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -74,7 +73,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -107,7 +106,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -123,7 +122,7 @@
 	 * The type arguments (element type: <code>Type</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeArguments = null;
 
@@ -279,18 +278,12 @@
 	/**
 	 * Returns the live ordered list of type arguments of this method
 	 * invocation (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type arguments
 	 *    (element type: <code>Type</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeArguments() {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java
index 158a300..0f64071 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRef.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java
index 7d0e656..490df5b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodRefParameter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,10 +17,23 @@
 /**
  * AST node for a parameter within a method reference ({@link MethodRef}).
  * These nodes only occur within doc comments ({@link Javadoc}).
+ * For JLS2:
  * <pre>
  * MethodRefParameter:
  * 		Type [ Identifier ]
  * </pre>
+ * For JLS3, the variable arity indicator was added:
+ * <pre>
+ * MethodRefParameter:
+ * 		Type [ <b>...</b> ] [ Identifier ]
+ * </pre>
+ * <p>
+ * Note: The 1.5 spec for the Javadoc tool does not mention the possibility
+ * of a variable arity indicator in method references. However, the 1.5
+ * Javadoc tool itself does indeed support it. Since it makes sense to have
+ * a way to explicitly refer to variable arity methods, it seems more likely
+ * that the Javadoc spec is wrong in this case.
+ * </p>
  * 
  * @see Javadoc
  * @since 3.0
@@ -35,6 +48,13 @@
 		new ChildPropertyDescriptor(MethodRefParameter.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
+	 * The "varargs" structural property of this node type (added in JLS3 API).
+	 * @since 3.1
+	 */
+	public static final SimplePropertyDescriptor VARARGS_PROPERTY = 
+		new SimplePropertyDescriptor(MethodRefParameter.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$
+	
+	/**
 	 * The "name" structural property of this node type.
 	 * @since 3.0
 	 */
@@ -45,15 +65,31 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
+	 * @since 3.0
 	 */
-	private static final List PROPERTY_DESCRIPTORS;
+	private static final List PROPERTY_DESCRIPTORS_2_0;
 	
+	/**
+	 * A list of property descriptors (element type: 
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 * @since 3.1
+	 */
+	private static final List PROPERTY_DESCRIPTORS_3_0;
+		
 	static {
 		List properyList = new ArrayList(3);
 		createPropertyList(MethodRefParameter.class, properyList);
 		addProperty(TYPE_PROPERTY, properyList);
 		addProperty(NAME_PROPERTY, properyList);
-		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+		PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(properyList);
+		
+		properyList = new ArrayList(3);
+		createPropertyList(MethodRefParameter.class, properyList);
+		addProperty(TYPE_PROPERTY, properyList);
+		addProperty(VARARGS_PROPERTY, properyList);
+		addProperty(NAME_PROPERTY, properyList);
+		PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(properyList);
 	}
 
 	/**
@@ -66,7 +102,11 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		return PROPERTY_DESCRIPTORS;
+		if (apiLevel == AST.JLS2_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_2_0;
+		} else {
+			return PROPERTY_DESCRIPTORS_3_0;
+		}
 	}
 			
 	/**
@@ -76,6 +116,14 @@
 	private Type type = null;
 
 	/**
+	 * Indicates the last parameter of a variable arity method;
+	 * defaults to false.
+	 * 
+	 * @since 3.1
+	 */
+	private boolean variableArity = false;
+
+	/**
 	 * The parameter name, or <code>null</code> if none; none by
 	 * default.
 	 */
@@ -84,7 +132,7 @@
 	/**
 	 * Creates a new AST node for a method referenece parameter owned by the given 
 	 * AST. By default, the node has an unspecified (but legal) type, 
-	 * and no parameter name.
+	 * not variable arity, and no parameter name.
 	 * <p>
 	 * N.B. This constructor is package-private.
 	 * </p>
@@ -125,6 +173,23 @@
 		// allow default implementation to flag the error
 		return super.internalGetSetChildProperty(property, get, child);
 	}
+	
+	/* (omit javadoc for this method)
+	 * Method declared on ASTNode.
+	 */
+	final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+		if (property == VARARGS_PROPERTY) {
+			if (get) {
+				return isVarargs();
+			} else {
+				setVarargs(value);
+				return false;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetBooleanProperty(property, get, value);
+	}
+	
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
@@ -139,6 +204,9 @@
 		MethodRefParameter result = new MethodRefParameter(target);
 		result.setSourceRange(this.getStartPosition(), this.getLength());
 		result.setType((Type) ASTNode.copySubtree(target, getType()));
+		if (this.ast.apiLevel >= AST.JLS3) {
+			result.setVarargs(isVarargs());
+		}
 		result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
 		return result;
 	}
@@ -205,6 +273,45 @@
 	}
 
 	/**
+	 * Returns whether this method reference parameter is for
+	 * the last parameter of a variable arity method (added in JLS3 API).
+	 * <p>
+	 * Note that the binding for the type <code>Foo</code>in the vararg method
+	 * reference <code>#fun(Foo...)</code> is always for the type as 
+	 * written; i.e., the type binding for <code>Foo</code>. However, if you
+	 * navigate from the MethodRef to its method binding to the
+	 * type binding for its last parameter, the type binding for the vararg
+	 * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
+	 * the way vararg methods get compiled.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if this is a variable arity parameter,
+	 *    and <code>false</code> otherwise
+	 * @exception UnsupportedOperationException if this operation is used in
+	 * a JLS2 AST
+	 * @since 3.1
+	 */ 
+	public boolean isVarargs() {
+		unsupportedIn2();
+		return this.variableArity;
+	}
+
+	/**
+	 * Sets whether this method reference parameter is for the last parameter of
+	 * a variable arity method (added in JLS3 API).
+	 * 
+	 * @param variableArity <code>true</code> if this is a variable arity
+	 *    parameter, and <code>false</code> otherwise
+	 * @since 3.1
+	 */ 
+	public void setVarargs(boolean variableArity) {
+		unsupportedIn2();
+		preValueChange(VARARGS_PROPERTY);
+		this.variableArity = variableArity;
+		postValueChange(VARARGS_PROPERTY);
+	}
+
+	/**
 	 * Returns the parameter name, or <code>null</code> if there is none.
 	 * 
 	 * @return the parameter name node, or <code>null</code> if there is none
@@ -235,7 +342,7 @@
 	 * Method declared on ASTNode.
 	 */
 	int memSize() {
-		return BASE_NODE_SIZE + 2 * 4;
+		return BASE_NODE_SIZE + 2 * 5;
 	}
 	
 	/* (omit javadoc for this method)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java
index 0f62bf1..f579c75 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Modifier.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java
index f176c79..dd79067 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NaiveASTFlattener.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -131,7 +131,7 @@
 	
 	/*
 	 * @see ASTVisitor#visit(AnnotationTypeDeclaration)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(AnnotationTypeDeclaration node) {
 		if (node.getJavadoc() != null) {
@@ -152,7 +152,7 @@
 	
 	/*
 	 * @see ASTVisitor#visit(AnnotationTypeMemberDeclaration)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(AnnotationTypeMemberDeclaration node) {
 		if (node.getJavadoc() != null) {
@@ -366,8 +366,8 @@
 			this.buffer.append(".");//$NON-NLS-1$
 		}
 		this.buffer.append("new ");//$NON-NLS-1$
-		if (node.getAST().apiLevel() == AST.JLS2) {
-			node.getName().accept(this);
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
+			node.internalGetName().accept(this);
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
 			if (!node.typeArguments().isEmpty()) {
@@ -496,7 +496,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(EnhancedForStatement)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(EnhancedForStatement node) {
 		printIndent();
@@ -511,7 +511,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(EnumConstantDeclaration)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(EnumConstantDeclaration node) {
 		if (node.getJavadoc() != null) {
@@ -539,7 +539,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(EnumDeclaration)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(EnumDeclaration node) {
 		if (node.getJavadoc() != null) {
@@ -611,7 +611,7 @@
 			node.getJavadoc().accept(this);
 		}
 		printIndent();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -698,10 +698,14 @@
 		this.buffer.append(node.getOperator().toString());
 		this.buffer.append(' ');
 		node.getRightOperand().accept(this);
-		for (Iterator it = node.extendedOperands().iterator(); it.hasNext(); ) {
-			this.buffer.append(node.getOperator().toString());
-			Expression e = (Expression) it.next();
-			e.accept(this);
+		final List extendedOperands = node.extendedOperands();
+		if (extendedOperands.size() != 0) {
+			this.buffer.append(' ');
+			for (Iterator it = extendedOperands.iterator(); it.hasNext(); ) {
+				this.buffer.append(node.getOperator().toString()).append(' ');
+				Expression e = (Expression) it.next();
+				e.accept(this);
+			}
 		}
 		return false;
 	}
@@ -723,7 +727,7 @@
 		if (node.getJavadoc() != null) {
 			node.getJavadoc().accept(this);
 		}
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -769,7 +773,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(MarkerAnnotation)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(MarkerAnnotation node) {
 		this.buffer.append("@");//$NON-NLS-1$
@@ -792,7 +796,7 @@
 	
 	/*
 	 * @see ASTVisitor#visit(MemberValuePair)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(MemberValuePair node) {
 		node.getName().accept(this);
@@ -829,6 +833,11 @@
 	 */
 	public boolean visit(MethodRefParameter node) {
 		node.getType().accept(this);
+		if (node.getAST().apiLevel() >= AST.JLS3) {
+			if (node.isVarargs()) {
+				this.buffer.append("...");//$NON-NLS-1$
+			}
+		}
 		if (node.getName() != null) {
 			this.buffer.append(" ");//$NON-NLS-1$
 			node.getName().accept(this);
@@ -844,7 +853,7 @@
 			node.getJavadoc().accept(this);
 		}
 		printIndent();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -862,8 +871,8 @@
 			}
 		}
 		if (!node.isConstructor()) {
-			if (node.getAST().apiLevel() == AST.JLS2) {
-				node.getReturnType().accept(this);
+			if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
+				node.internalGetReturnType().accept(this);
 			} else {
 				if (node.getReturnType2() != null) {
 					node.getReturnType2().accept(this);
@@ -942,7 +951,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(Modifier)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(Modifier node) {
 		this.buffer.append(node.getKeyword().toString());
@@ -951,7 +960,7 @@
 	
 	/*
 	 * @see ASTVisitor#visit(NormalAnnotation)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(NormalAnnotation node) {
 		this.buffer.append("@");//$NON-NLS-1$
@@ -1007,7 +1016,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(ParameterizedType)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(ParameterizedType node) {
 		node.getType().accept(this);
@@ -1071,7 +1080,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(QualifiedType)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(QualifiedType node) {
 		node.getQualifier().accept(this);
@@ -1111,7 +1120,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(SingleMemberAnnotation)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(SingleMemberAnnotation node) {
 		this.buffer.append("@");//$NON-NLS-1$
@@ -1127,7 +1136,7 @@
 	 */
 	public boolean visit(SingleVariableDeclaration node) {
 		printIndent();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -1385,7 +1394,7 @@
 		if (node.getJavadoc() != null) {
 			node.getJavadoc().accept(this);
 		}
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -1407,15 +1416,15 @@
 			}
 		}
 		this.buffer.append(" ");//$NON-NLS-1$
-		if (node.getAST().apiLevel() == AST.JLS2) {
-			if (node.getSuperclass() != null) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
+			if (node.internalGetSuperclass() != null) {
 				this.buffer.append("extends ");//$NON-NLS-1$
-				node.getSuperclass().accept(this);
+				node.internalGetSuperclass().accept(this);
 				this.buffer.append(" ");//$NON-NLS-1$
 			}
-			if (!node.superInterfaces().isEmpty()) {
+			if (!node.internalSuperInterfaces().isEmpty()) {
 				this.buffer.append(node.isInterface() ? "extends " : "implements ");//$NON-NLS-2$//$NON-NLS-1$
-				for (Iterator it = node.superInterfaces().iterator(); it.hasNext(); ) {
+				for (Iterator it = node.internalSuperInterfaces().iterator(); it.hasNext(); ) {
 					Name n = (Name) it.next();
 					n.accept(this);
 					if (it.hasNext()) {
@@ -1471,8 +1480,8 @@
 	 * @see ASTVisitor#visit(TypeDeclarationStatement)
 	 */
 	public boolean visit(TypeDeclarationStatement node) {
-		if (node.getAST().apiLevel() == AST.JLS2) {
-			node.getTypeDeclaration().accept(this);
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
+			node.internalGetTypeDeclaration().accept(this);
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
 			node.getDeclaration().accept(this);
@@ -1491,7 +1500,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(TypeParameter)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(TypeParameter node) {
 		node.getName().accept(this);
@@ -1512,7 +1521,7 @@
 	 * @see ASTVisitor#visit(VariableDeclarationExpression)
 	 */
 	public boolean visit(VariableDeclarationExpression node) {
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -1550,7 +1559,7 @@
 	 */
 	public boolean visit(VariableDeclarationStatement node) {
 		printIndent();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == AST.JLS2_INTERNAL) {
 			printModifiers(node.getModifiers());
 		}
 		if (node.getAST().apiLevel() >= AST.JLS3) {
@@ -1571,7 +1580,7 @@
 
 	/*
 	 * @see ASTVisitor#visit(WildcardType)
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public boolean visit(WildcardType node) {
 		this.buffer.append("?");//$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java
index bea5692..751c0b7 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Name.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java
index fa692d5..ea9e6af 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeEventHandler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java
index 9302c20..ec962ea 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NodeSearcher.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java
index c724c4a..cda3793 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NormalAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,19 +21,13 @@
  *   <b>@</b> TypeName <b>(</b> [ MemberValuePair { <b>,</b> MemberValuePair } ] <b>)</b>
  * </pre>
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
- * @since 3.0
+ * 
+ * @since 3.1
  */
 public final class NormalAnnotation extends Annotation {
 	
 	/**
 	 * The "typeName" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY = 
 		internalTypeNamePropertyFactory(NormalAnnotation.class);
@@ -48,7 +42,6 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
 	 */
 	private static final List PROPERTY_DESCRIPTORS;
 	
@@ -67,7 +60,6 @@
 	 * @param apiLevel the API level; one of the AST.JLS* constants
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -98,7 +90,6 @@
 
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
-	 * @since 3.0
 	 */
 	final List internalStructuralPropertiesForType(int apiLevel) {
 		return propertyDescriptors(apiLevel);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java
index e2e7e0b..867398f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NullLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java
index b2059ca..1ee45ea 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NumberLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -153,6 +153,7 @@
 	 * @exception IllegalArgumentException if the argument is incorrect
 	 */ 
 	public void setToken(String token) {
+		// update internalSetToken(String) if this is changed
 		if (token == null || token.length() == 0) {
 			throw new IllegalArgumentException();
 		}
@@ -197,6 +198,14 @@
 	}
 	
 	/* (omit javadoc for this method)
+	 * This method is a copy of setToken(String) that doesn't do any validation.
+	 */
+	void internalSetToken(String token) {
+		preValueChange(TOKEN_PROPERTY);
+		this.tokenValue = token;
+		postValueChange(TOKEN_PROPERTY);
+	}
+	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
 	int memSize() {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java
index 2e0c67f..31047dd 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java
index a816170..2545f3c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PackageDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,7 +41,7 @@
 
 	/**
 	 * The "annotations" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY = 
 		new ChildListPropertyDescriptor(PackageDeclaration.class, "annotations", Annotation.class, CYCLE_RISK); //$NON-NLS-1$
@@ -65,7 +65,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -95,7 +95,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -113,7 +113,7 @@
 	 * The annotations (element type: <code>Annotation</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList annotations = null;
 	
@@ -231,18 +231,12 @@
 	/**
 	 * Returns the live ordered list of annotations of this 
 	 * package declaration (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of annotations
 	 *    (element type: <code>Annotation</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List annotations() {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java
index c5f8db7..2a4cbff 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2004 IBM Corporation and others.
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,27 +24,23 @@
  * </pre>
  * The first type may be a simple type or a qualified type;
  * other kinds of types are meaningless.
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class ParameterizedType extends Type {
+    /**
+     * This index represents the position inside a parameterized qualified type.
+     */
+    int index;
 	
 	/**
 	 * The "type" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor TYPE_PROPERTY = 
 		new ChildPropertyDescriptor(ParameterizedType.class, "type", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "typeArguments" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
 		new ChildListPropertyDescriptor(ParameterizedType.class, "typeArguments", Type.class, CYCLE_RISK); //$NON-NLS-1$
@@ -73,7 +69,6 @@
 
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -237,7 +232,7 @@
 	 */
 	int memSize() {
 		// treat Code as free
-		return BASE_NODE_SIZE + 2 * 4;
+		return BASE_NODE_SIZE + 3 * 4;
 	}
 	
 	/* (omit javadoc for this method)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java
index da94e9d..1d46746 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParenthesizedExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java
index 71b0fad..65ddc4c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PostfixExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java
index 6e6f9df..f7fe3df 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrefixExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java
index 0756efe..abc8ac9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/PrimitiveType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java
index 0cca1f5..14c0c0d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -264,7 +264,7 @@
 	 * Method declared on ASTNode.
 	 */
 	int memSize() {
-		return BASE_NAME_NODE_SIZE + 2 * 4;
+		return BASE_NAME_NODE_SIZE + 3 * 4;
 	}
 	
 	/* (omit javadoc for this method)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java
index 70a7280..2103e27 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2004 IBM Corporation and others.
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,20 +41,22 @@
  * became possible as of JLS3; only the second form existed in JLS2 API.)
  * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class QualifiedType extends Type {
+    /**
+     * This index represents the position inside a parameterized qualified type.
+     */
+    int index;
 	
 	/**
 	 * The "qualifier" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor QUALIFIER_PROPERTY = 
 		new ChildPropertyDescriptor(QualifiedType.class, "qualifier", Type.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "name" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor NAME_PROPERTY = 
 		new ChildPropertyDescriptor(QualifiedType.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -82,7 +84,6 @@
 	 * <code>AST.JLS&ast;</code> constants
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -267,7 +268,7 @@
 	 */
 	int memSize() {
 		// treat Code as free
-		return BASE_NODE_SIZE + 2 * 4;
+		return BASE_NODE_SIZE + 3 * 4;
 	}
 	
 	/* (omit javadoc for this method)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java
index cd22e5a..686532f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ReturnStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java
index aa1e16f..04bff78 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleName.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -171,17 +171,23 @@
 	 * @exception IllegalArgumentException if the identifier is invalid
 	 */ 
 	public void setIdentifier(String identifier) {
+		// update internalSetIdentifier if this is changed
 		if (identifier == null) {
 			throw new IllegalArgumentException();
 		}
 		Scanner scanner = this.ast.scanner;
 		char[] source = identifier.toCharArray();
 		scanner.setSource(source);
-		scanner.resetTo(0, source.length);
+		final int length = source.length;
+		scanner.resetTo(0, length);
 		try {
 			int tokenType = scanner.getNextToken();
 			switch(tokenType) {
 				case TerminalTokens.TokenNameIdentifier:
+					if (scanner.getCurrentTokenEndPosition() != length - 1) {
+						// this is the case when there is only one identifier see 87849
+						throw new IllegalArgumentException();
+					}
 					break;
 				default:
 					throw new IllegalArgumentException();
@@ -194,6 +200,15 @@
 		postValueChange(IDENTIFIER_PROPERTY);
 	}
 
+	/* (omit javadoc for this method)
+	 * This method is a copy of setIdentifier(String) that doesn't do any validation.
+	 */
+	void internalSetIdentifier(String ident) {
+		preValueChange(IDENTIFIER_PROPERTY);
+		this.identifier = ident;
+		postValueChange(IDENTIFIER_PROPERTY);
+	}
+	
 	/**
 	 * Returns whether this simple name represents a name that is being defined,
 	 * as opposed to one being referenced. The following positions are considered
@@ -273,7 +288,7 @@
 	 * Method declared on ASTNode.
 	 */
 	int memSize() {
-		int size = BASE_NAME_NODE_SIZE + 1 * 4;
+		int size = BASE_NAME_NODE_SIZE + 2 * 4;
 		if (identifier != MISSING_IDENTIFIER) {
 			// everything but our missing id costs
 			size += stringSize(identifier);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java
index 14ad1a1..7d4563b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimplePropertyDescriptor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java
index 6c39c23..6525a4c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SimpleType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java
index f1ff4f2..60ea70a 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleMemberAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,26 +24,19 @@
  * Within annotations, only certain kinds of expressions are meaningful,
  * including other annotations.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
- * @since 3.0
+ * 
+ * @since 3.1
  */
 public final class SingleMemberAnnotation extends Annotation {
 	
 	/**
 	 * The "typeName" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor TYPE_NAME_PROPERTY = 
 		internalTypeNamePropertyFactory(SingleMemberAnnotation.class);
 
 	/**
 	 * The "value" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor VALUE_PROPERTY = 
 		new ChildPropertyDescriptor(SingleMemberAnnotation.class, "value", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
@@ -52,7 +45,6 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
 	 */
 	private static final List PROPERTY_DESCRIPTORS;
 	
@@ -71,7 +63,6 @@
 	 * @param apiLevel the API level; one of the AST.JLS* constants
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -100,7 +91,6 @@
 
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
-	 * @since 3.0
 	 */
 	final List internalStructuralPropertiesForType(int apiLevel) {
 		return propertyDescriptors(apiLevel);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java
index 8e44c29..ede1607 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SingleVariableDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,13 +41,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-    // TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		new SimplePropertyDescriptor(SingleVariableDeclaration.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
@@ -68,7 +67,7 @@
 
 	/**
 	 * The "varargs" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final SimplePropertyDescriptor VARARGS_PROPERTY = 
 		new SimplePropertyDescriptor(SingleVariableDeclaration.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$
@@ -99,7 +98,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -135,7 +134,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -147,7 +146,7 @@
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
 	 * 
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList modifiers = null;
 	
@@ -173,7 +172,7 @@
 	 * Indicates the last parameter of a variable arity method;
 	 * defaults to false.
 	 * 
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private boolean variableArity = false;
 
@@ -336,7 +335,7 @@
 	ASTNode clone0(AST target) {
 		SingleVariableDeclaration result = new SingleVariableDeclaration(target);
 		result.setSourceRange(this.getStartPosition(), this.getLength());
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			result.setModifiers(getModifiers());
 		} else {
 			result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
@@ -387,7 +386,7 @@
 	 *    (element type: <code>IExtendedModifier</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List modifiers() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -439,12 +438,22 @@
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
 	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>modifiers()</code> which contains a list of  a <code>Modifier</code> nodes.
 	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
 	    supportedOnlyIn2();
 		preValueChange(MODIFIERS_PROPERTY);
-		this.modifierFlags = modifiers;
+		this.modifierFlags = pmodifiers;
 		postValueChange(MODIFIERS_PROPERTY);
 	}
 
@@ -523,17 +532,20 @@
 	 * Returns whether this declaration declares the last parameter of
 	 * a variable arity method (added in JLS3 API).
 	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
+	 * Note that the binding for the type <code>Foo</code>in the vararg method
+	 * declaration <code>void fun(Foo... args)</code> is always for the type as 
+	 * written; i.e., the type binding for <code>Foo</code>. However, if you
+	 * navigate from the method declaration to its method binding to the
+	 * type binding for its last parameter, the type binding for the vararg
+	 * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
+	 * the way vararg methods get compiled.
 	 * </p>
 	 * 
 	 * @return <code>true</code> if this is a variable arity parameter declaration,
 	 *    and <code>false</code> otherwise
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public boolean isVarargs() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -546,16 +558,10 @@
 	/**
 	 * Sets whether this declaration declares the last parameter of
 	 * a variable arity method (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @param variableArity <code>true</code> if this is a variable arity
 	 *    parameter declaration, and <code>false</code> otherwise
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public void setVarargs(boolean variableArity) {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
index e7f483d..f4ffccf 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Statement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
index c0e5307..7ad9d90 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StringLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -165,6 +165,7 @@
 	 * @exception IllegalArgumentException if the argument is incorrect
 	 */ 
 	public void setEscapedValue(String token) {
+		// update internalSetEscapedValue(String) if this is changed
 		if (token == null) {
 			throw new IllegalArgumentException("Token cannot be null"); //$NON-NLS-1$
 		}
@@ -188,6 +189,15 @@
 		postValueChange(ESCAPED_VALUE_PROPERTY);
 	}
 
+	/* (omit javadoc for this method)
+	 * This method is a copy of setEscapedValue(String) that doesn't do any validation.
+	 */
+	void internalSetEscapedValue(String token) {
+		preValueChange(ESCAPED_VALUE_PROPERTY);
+		this.escapedValue = token;
+		postValueChange(ESCAPED_VALUE_PROPERTY);
+	}
+
 	/**
 	 * Returns the value of this literal node. 
 	 * <p>
@@ -222,7 +232,7 @@
 			int tokenType = scanner.getNextToken();
 			switch(tokenType) {
 				case TerminalTokens.TokenNameStringLiteral:
-					return new String(scanner.getCurrentTokenSourceString());
+					return scanner.getCurrentStringLiteral();
 				default:
 					throw new IllegalArgumentException();
 			}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java
index 2c04bff..5f95108 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/StructuralPropertyDescriptor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java
index 70884ad..af68963 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperConstructorInvocation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -42,7 +42,7 @@
 
 	/**
 	 * The "typeArguments" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
 		new ChildListPropertyDescriptor(SuperConstructorInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -66,7 +66,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -97,7 +97,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -113,7 +113,7 @@
 	 * The type arguments (element type: <code>Type</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeArguments = null;
 
@@ -255,18 +255,12 @@
 	/**
 	 * Returns the live ordered list of type arguments of this constructor
 	 * invocation (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type arguments
 	 *    (element type: <code>Type</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeArguments() {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java
index d79a8d2..952461e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperFieldAccess.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java
index e6bd344..36c7161 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SuperMethodInvocation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -43,7 +43,7 @@
 
 	/**
 	 * The "typeArguments" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = 
 		new ChildListPropertyDescriptor(SuperMethodInvocation.class, "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -74,7 +74,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -107,7 +107,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -123,7 +123,7 @@
 	 * The type arguments (element type: <code>Type</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeArguments = null;
 
@@ -277,18 +277,12 @@
 	/**
 	 * Returns the live ordered list of type arguments of this method
 	 * invocation (added in JLS3 API).
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type arguments
 	 *    (element type: <code>Type</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeArguments() {
 		// more efficient than just calling unsupportedIn2() to check
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
index f893c77..27f66db 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java
index 9c93441..a5f585a 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -223,8 +223,8 @@
 	 * Within this list, <code>SwitchCase</code> nodes mark the start of 
 	 * the switch groups.
 	 * 
-	 * @return the live list of switch group nodes
-	 *    (element type: <code>SwitchGroups</code>)
+	 * @return the live list of statement nodes
+	 *    (element type: <code>Statement</code>)
 	 */ 
 	public List statements() {
 		return this.statements;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java
index 1c0860f..4c4c8c6 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SynchronizedStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java
index 728057c..fae57ca 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TagElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java
index 7775842..dc04c6b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TextElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java
index e6d7085..09a1273 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThisExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java
index 8c9135d..74cc650 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ThrowStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java
index aab8534..b9d9ab5 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TryStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java
index 9b6ea87..c4c3676 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Type.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -105,7 +105,7 @@
 	 * 
 	 * @return <code>true</code> if this is a parameterized type, and 
 	 *    <code>false</code> otherwise
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public final boolean isParameterizedType() {
 		return (this instanceof ParameterizedType);
@@ -133,7 +133,7 @@
 	 * 
 	 * @return <code>true</code> if this is a qualified type, and 
 	 *    <code>false</code> otherwise
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public final boolean isQualifiedType() {
 		return (this instanceof QualifiedType);
@@ -149,7 +149,7 @@
 	 * 
 	 * @return <code>true</code> if this is a wildcard type, and 
 	 *    <code>false</code> otherwise
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public final boolean isWildcardType() {
 		return (this instanceof WildcardType);
@@ -168,4 +168,4 @@
 	public final ITypeBinding resolveBinding() {
 		return this.ast.getBindingResolver().resolveType(this);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
index b33ff84..81c376d 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -30,15 +30,19 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.env.IDependent;
 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
@@ -105,8 +109,8 @@
 			return null;
 		IPackageFragment pkg = getPackageFragment(fileName, lastSlash);
 		if (pkg == null) return null;
-		char[] simpleName = CharOperation.subarray(fileName, lastSlash+1, fileName.length);
-		return pkg.getClassFile(new String(simpleName));
+		int start;
+		return pkg.getClassFile(new String(fileName, start = lastSlash+1, fileName.length - start));
 	}
 	
 	/*
@@ -119,8 +123,8 @@
 		if (lastSlash == -1) return null;
 		IPackageFragment pkg = getPackageFragment(slashSeparatedFileName, lastSlash);
 		if (pkg == null) return null;
-		char[] simpleName = CharOperation.subarray(slashSeparatedFileName, lastSlash+1, slashSeparatedFileName.length);
-		ICompilationUnit cu = pkg.getCompilationUnit(new String(simpleName));
+		int start;
+		ICompilationUnit cu = pkg.getCompilationUnit(new String(slashSeparatedFileName, start =  lastSlash+1, slashSeparatedFileName.length - start));
 		if (this.resolver instanceof DefaultBindingResolver) {
 			ICompilationUnit workingCopy = cu.findWorkingCopy(((DefaultBindingResolver) this.resolver).workingCopyOwner);
 			if (workingCopy != null) 
@@ -219,22 +223,71 @@
 	}
 
 	/*
+	 * @see ITypeBinding#getDeclaringMethod()
+	 */
+	public IMethodBinding getDeclaringMethod() {
+		if (this.binding instanceof LocalTypeBinding) {
+			LocalTypeBinding localTypeBinding = (LocalTypeBinding) this.binding;
+			MethodBinding methodBinding = localTypeBinding.enclosingMethod;
+			if (methodBinding != null) {
+				try {
+					return this.resolver.getMethodBinding(localTypeBinding.enclosingMethod);
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+				}
+			}
+		} else if (this.binding.isTypeVariable()) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			Binding declaringElement = typeVariableBinding.declaringElement;
+			if (declaringElement instanceof MethodBinding) {
+				try {
+					return this.resolver.getMethodBinding((MethodBinding)declaringElement);
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+				}				
+			}
+		}
+		return null;
+	}
+
+	/*
 	 * @see ITypeBinding#getDeclaringClass()
 	 */
 	public ITypeBinding getDeclaringClass() {
-		if (this.binding.isArrayType() || this.binding.isBaseType()) {
-			return null;
-		}
-		ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
-		if (referenceBinding.isNestedType()) {
-			try {
-				return this.resolver.getTypeBinding(referenceBinding.enclosingType());
-			} catch (RuntimeException e) {
-				/* in case a method cannot be resolvable due to missing jars on the classpath
-				 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
-				 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
-				 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
-				 */
+		if (isClass() || isInterface() || isEnum()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			if (referenceBinding.isNestedType()) {
+				try {
+					return this.resolver.getTypeBinding(referenceBinding.enclosingType());
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+				}
+			}
+		} else if (this.binding.isTypeVariable()) {
+			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+			Binding declaringElement = typeVariableBinding.declaringElement;
+			if (declaringElement instanceof ReferenceBinding) {
+				try {
+					return this.resolver.getTypeBinding((ReferenceBinding)declaringElement);
+				} catch (RuntimeException e) {
+					/* in case a method cannot be resolvable due to missing jars on the classpath
+					 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
+					 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
+					 */
+				}				
 			}
 		}
 		return null;
@@ -262,27 +315,29 @@
 		return resolver.getTypeBinding(arrayBinding.leafComponentType);
 	}
 
-	/**
-	 * @deprecated Use {@link #getGenericType()} instead.
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeDeclaration()
 	 */
-	// TODO (jeem) - remove before 3.1M5 (bug 80800)
-	public ITypeBinding getErasure() {
-		return getGenericType();
+	public ITypeBinding getTypeDeclaration() {
+		if (this.binding instanceof ParameterizedTypeBinding)
+			return this.resolver.getTypeBinding(((ParameterizedTypeBinding)this.binding).type);
+		return this;
 	}
 
 	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getGenericType()
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getErasure()
 	 */
-	public ITypeBinding getGenericType() {
+	public ITypeBinding getErasure() {
 		return this.resolver.getTypeBinding(this.binding.erasure());
 	}
 
-	/*
-	 * @see ITypeBinding#getInterfaces()
-	 */
 	public ITypeBinding[] getInterfaces() {
-		if (this.binding == null || this.binding.isArrayType() || this.binding.isBaseType()) {
+		if (this.binding == null) 
 			return NO_TYPE_BINDINGS;
+		switch (this.binding.kind()) {
+			case Binding.ARRAY_TYPE :
+			case Binding.BASE_TYPE :
+				return NO_TYPE_BINDINGS;
 		}
 		ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
 		ReferenceBinding[] interfaces = null;
@@ -310,11 +365,14 @@
 		}
 	}
 	
-	/*
-	 * @see IBinding#getJavaElement()
-	 */
 	public IJavaElement getJavaElement() {
-		if (this.binding == null || this.binding.isArrayType() || this.binding.isBaseType()) return null;
+		if (this.binding == null) 
+			return null;
+		switch (this.binding.kind()) {
+			case Binding.ARRAY_TYPE :
+			case Binding.BASE_TYPE :
+				return null;
+		}
 		ReferenceBinding referenceBinding;
 		if (this.binding.isParameterizedType() || this.binding.isRawType())
 			referenceBinding = (ReferenceBinding) this.binding.erasure();
@@ -400,94 +458,114 @@
 				return accessFlags & ~Modifier.FINAL;
 			}
 			return accessFlags;
+		} else if (isAnnotation()) {
+			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
+			// clear the AccAbstract, AccAnnotation and the AccInterface bits
+			return accessFlags & ~(IConstants.AccAbstract | IConstants.AccInterface | IConstants.AccAnnotation);			
 		} else if (isInterface()) {
 			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
 			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
 			// clear the AccAbstract and the AccInterface bits
-			return accessFlags & ~(Modifier.ABSTRACT | 0x200);
+			return accessFlags & ~(IConstants.AccAbstract | IConstants.AccInterface);
 		} else if (isEnum()) {
 			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
 			final int accessFlags = referenceBinding.getAccessFlags() & VALID_MODIFIERS;
 			// clear the AccEnum bits
-			return accessFlags & ~0x4000;
+			return accessFlags & ~IConstants.AccEnum;
 		} else {
 			return 0;
 		}
 	}
 
 	public String getName() {
-		if (isWildcardType()) {
-			WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
-			StringBuffer buffer = new StringBuffer();
-			buffer.append(TypeConstants.WILDCARD_NAME);
-			if (wildcardBinding.bound != null) {
-				switch(wildcardBinding.kind) {
-			        case Wildcard.SUPER :
-			        	buffer.append(TypeConstants.WILDCARD_SUPER);
-			            break;
-			        case Wildcard.EXTENDS :
-			        	buffer.append(TypeConstants.WILDCARD_EXTENDS);
-				}
-				buffer.append(getBound().getName());
-			}
-			return String.valueOf(buffer);
-		}
-		if (isParameterizedType()) {
-			ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding;
-			StringBuffer buffer = new StringBuffer();
-			buffer.append(parameterizedTypeBinding.sourceName());
-			ITypeBinding[] typeArguments = getTypeArguments();
-			final int typeArgumentsLength = typeArguments.length;
-			if (typeArgumentsLength != 0) {
-				buffer.append('<');
-				for (int i = 0, max = typeArguments.length; i < max; i++) {
-					if (i > 0) {
-						buffer.append(',');
+		StringBuffer buffer;
+		switch (this.binding.kind()) {
+
+			case Binding.WILDCARD_TYPE :
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				buffer = new StringBuffer();
+				buffer.append(TypeConstants.WILDCARD_NAME);
+				if (wildcardBinding.bound != null) {
+					switch(wildcardBinding.boundKind) {
+				        case Wildcard.SUPER :
+				        	buffer.append(TypeConstants.WILDCARD_SUPER);
+				            break;
+				        case Wildcard.EXTENDS :
+				        	buffer.append(TypeConstants.WILDCARD_EXTENDS);
 					}
-					buffer.append(typeArguments[i].getName());
+					buffer.append(getBound().getName());
 				}
-				buffer.append('>');	
-			}
-			return String.valueOf(buffer);
+				return String.valueOf(buffer);
+				
+			case Binding.TYPE_PARAMETER :
+				if (isCapture()) {
+					return NO_NAME;
+				}
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+				return new String(typeVariableBinding.sourceName);
+				
+			case Binding.PARAMETERIZED_TYPE :
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding;
+				buffer = new StringBuffer();
+				buffer.append(parameterizedTypeBinding.sourceName());
+				ITypeBinding[] typeArguments = getTypeArguments();
+				final int typeArgumentsLength = typeArguments.length;
+				if (typeArgumentsLength != 0) {
+					buffer.append('<');
+					for (int i = 0, max = typeArguments.length; i < max; i++) {
+						if (i > 0) {
+							buffer.append(',');
+						}
+						buffer.append(typeArguments[i].getName());
+					}
+					buffer.append('>');	
+				}
+				return String.valueOf(buffer);
+				
+			case Binding.RAW_TYPE :				
+				return getTypeDeclaration().getName();
+
+			case Binding.ARRAY_TYPE :
+				ITypeBinding elementType = getElementType();
+				if (elementType.isLocal() || elementType.isAnonymous() || elementType.isCapture()) {
+					return NO_NAME;
+				}				
+				int dimensions = getDimensions();
+				char[] brackets = new char[dimensions * 2];
+				for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
+					brackets[i] = ']';
+					brackets[i - 1] = '[';
+				}
+				buffer = new StringBuffer(elementType.getName());
+				buffer.append(brackets);
+				return String.valueOf(buffer);
+
+			default :
+				if (isPrimitive() || isNullType()) {
+					BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
+					return new String(baseTypeBinding.simpleName);
+				}
+				if (isAnonymous()) {
+					return NO_NAME;
+				}
+				return new String(this.binding.sourceName());
 		}
-		if (isRawType()) {
-			return getGenericType().getName();
-		}
-		if (isPrimitive() || isNullType()) {
-			BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
-			return new String(baseTypeBinding.simpleName);
-		}
-		if (isArray()) {
-			int dimensions = getDimensions();
-			char[] brackets = new char[dimensions * 2];
-			for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
-				brackets[i] = ']';
-				brackets[i - 1] = '[';
-			}
-			StringBuffer buffer = new StringBuffer(getElementType().getName());
-			buffer.append(brackets);
-			return String.valueOf(buffer);
-		}
-		if (isAnonymous()) {
-			return NO_NAME;
-		}
-		if (isTypeVariable()) {
-			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
-			return new String(typeVariableBinding.sourceName);
-		}
-		return new String(this.binding.sourceName());
 	}
 	
 	/*
 	 * @see ITypeBinding#getPackage()
 	 */
 	public IPackageBinding getPackage() {
-		if (this.binding.isBaseType() || this.binding.isArrayType()) {
-			return null;
-		} else {
-			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
-			return this.resolver.getPackageBinding(referenceBinding.getPackage());
+		switch (this.binding.kind()) {
+			case Binding.BASE_TYPE :
+			case Binding.ARRAY_TYPE :
+			case Binding.TYPE_PARAMETER : // includes capture scenario
+			case Binding.WILDCARD_TYPE :
+				return null;
 		}
+		ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
+		return this.resolver.getPackageBinding(referenceBinding.getPackage());
 	}
 	
 	/*
@@ -497,13 +575,13 @@
 	private IPackageFragment getPackageFragment(char[] fileName, int lastSlash) {
 		int jarSeparator = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, fileName);
 		if (jarSeparator != -1) {
-			String jarMemento = new String(CharOperation.subarray(fileName, 0, jarSeparator));
+			String jarMemento = new String(fileName, 0, jarSeparator);
 			IPackageFragmentRoot root = (IPackageFragmentRoot) JavaCore.create(jarMemento);
 			char[] pkgName = CharOperation.subarray(fileName, jarSeparator+1, lastSlash);
 			CharOperation.replace(pkgName, '/', '.');
 			return root.getPackageFragment(new String(pkgName));
 		} else {
-			Path path = new Path(new String(CharOperation.subarray(fileName, 0, lastSlash)));
+			Path path = new Path(new String(fileName, 0, lastSlash));
 			IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
 			IContainer folder = path.segmentCount() == 1 ? workspaceRoot.getProject(path.lastSegment()) : (IContainer) workspaceRoot.getFolder(path);
 			IJavaElement element = JavaCore.create(folder);
@@ -526,102 +604,132 @@
 	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getQualifiedName()
 	 */
 	public String getQualifiedName() {
-		if (isAnonymous() || isLocal()) {
-			return NO_NAME;
-		}
-		if (isPrimitive() || isNullType()) {
-			BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
-			return new String(baseTypeBinding.simpleName);
-		}
-		if (isWildcardType()) {
-			WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
-			StringBuffer buffer = new StringBuffer();
-			buffer.append(TypeConstants.WILDCARD_NAME);
-			final ITypeBinding bound = getBound();
-			if (bound != null) {
-				switch(wildcardBinding.kind) {
-			        case Wildcard.SUPER :
-			        	buffer.append(TypeConstants.WILDCARD_SUPER);
-			            break;
-			        case Wildcard.EXTENDS :
-			        	buffer.append(TypeConstants.WILDCARD_EXTENDS);
-				}
-				buffer.append(bound.getQualifiedName());
-			}
-			return String.valueOf(buffer);
-		}
-		if (isRawType()) {
-			return getGenericType().getQualifiedName();
-		}
-		if (isArray()) {
-			ITypeBinding elementType = getElementType();
-			if (elementType.isLocal() || elementType.isAnonymous()) {
-				return NO_NAME;
-			}
-			final int dimensions = getDimensions();
-			char[] brackets = new char[dimensions * 2];
-			for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
-				brackets[i] = ']';
-				brackets[i - 1] = '[';
-			}
-			StringBuffer buffer = new StringBuffer(elementType.getQualifiedName());
-			buffer.append(brackets);
-			return String.valueOf(buffer);
-		}
-		if (isTypeVariable()) {
-			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
-			return new String(typeVariableBinding.sourceName);
-		}
-		if (isMember()) {
-			StringBuffer buffer = new StringBuffer();
-			buffer
-				.append(getDeclaringClass().getQualifiedName())
-				.append('.')
-				.append(getName());
-			return String.valueOf(buffer);
-		}
-		if (isParameterizedType()) {
-			StringBuffer buffer = new StringBuffer();
-			buffer.append(getGenericType().getQualifiedName());
-			ITypeBinding[] typeArguments = getTypeArguments();
-			final int typeArgumentsLength = typeArguments.length;
-			if (typeArgumentsLength != 0) {
-				buffer.append('<');
-				for (int i = 0, max = typeArguments.length; i < max; i++) {
-					if (i > 0) {
-						buffer.append(',');
+		StringBuffer buffer;
+		switch (this.binding.kind()) {
+			
+			case Binding.WILDCARD_TYPE :
+				WildcardBinding wildcardBinding = (WildcardBinding) this.binding;
+				buffer = new StringBuffer();
+				buffer.append(TypeConstants.WILDCARD_NAME);
+				final ITypeBinding bound = getBound();
+				if (bound != null) {
+					switch(wildcardBinding.boundKind) {
+				        case Wildcard.SUPER :
+				        	buffer.append(TypeConstants.WILDCARD_SUPER);
+				            break;
+				        case Wildcard.EXTENDS :
+				        	buffer.append(TypeConstants.WILDCARD_EXTENDS);
 					}
-					buffer.append(typeArguments[i].getQualifiedName());
+					buffer.append(bound.getQualifiedName());
 				}
-				buffer.append('>');
-			}
-			return String.valueOf(buffer);
-		}
-		if (isRawType()) {
-			return getGenericType().getQualifiedName();
-		}
-		PackageBinding packageBinding = this.binding.getPackage();
+				return String.valueOf(buffer);
 		
-		StringBuffer buffer = new StringBuffer();
-		if (packageBinding != null && packageBinding.compoundName != CharOperation.NO_CHAR_CHAR) {
-			buffer.append(CharOperation.concatWith(packageBinding.compoundName, '.')).append('.');
+			case Binding.RAW_TYPE :
+				return getTypeDeclaration().getQualifiedName();
+				
+			case Binding.ARRAY_TYPE :
+				ITypeBinding elementType = getElementType();
+				if (elementType.isLocal() || elementType.isAnonymous() || elementType.isCapture()) {
+					return NO_NAME;
+				}
+				final int dimensions = getDimensions();
+				char[] brackets = new char[dimensions * 2];
+				for (int i = dimensions * 2 - 1; i >= 0; i -= 2) {
+					brackets[i] = ']';
+					brackets[i - 1] = '[';
+				}
+				buffer = new StringBuffer(elementType.getQualifiedName());
+				buffer.append(brackets);
+				return String.valueOf(buffer);
+				
+			case Binding.TYPE_PARAMETER :
+				if (isCapture()) {
+					return NO_NAME;
+				}				
+				TypeVariableBinding typeVariableBinding = (TypeVariableBinding) this.binding;
+				return new String(typeVariableBinding.sourceName);
+				
+			case Binding.PARAMETERIZED_TYPE :
+				buffer = new StringBuffer();
+				if (isMember()) {
+					buffer
+						.append(getDeclaringClass().getQualifiedName())
+						.append('.');
+					ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) this.binding;
+					buffer.append(parameterizedTypeBinding.sourceName());
+					ITypeBinding[] typeArguments = getTypeArguments();
+					final int typeArgumentsLength = typeArguments.length;
+					if (typeArgumentsLength != 0) {
+						buffer.append('<');
+						for (int i = 0, max = typeArguments.length; i < max; i++) {
+							if (i > 0) {
+								buffer.append(',');
+							}
+							buffer.append(typeArguments[i].getQualifiedName());
+						}
+						buffer.append('>');	
+					}
+					return String.valueOf(buffer);
+				}				
+				buffer.append(getTypeDeclaration().getQualifiedName());
+				ITypeBinding[] typeArguments = getTypeArguments();
+				final int typeArgumentsLength = typeArguments.length;
+				if (typeArgumentsLength != 0) {
+					buffer.append('<');
+					for (int i = 0, max = typeArguments.length; i < max; i++) {
+						if (i > 0) {
+							buffer.append(',');
+						}
+						buffer.append(typeArguments[i].getQualifiedName());
+					}
+					buffer.append('>');
+				}
+				return String.valueOf(buffer);
+				
+			default :
+				if (isAnonymous() || isLocal()) {
+					return NO_NAME;
+				}
+				if (isPrimitive() || isNullType()) {
+					BaseTypeBinding baseTypeBinding = (BaseTypeBinding) this.binding;
+					return new String(baseTypeBinding.simpleName);
+				}
+				if (isMember()) {
+					buffer = new StringBuffer();
+					buffer
+						.append(getDeclaringClass().getQualifiedName())
+						.append('.');
+					buffer.append(getName());
+					return String.valueOf(buffer);
+				}
+				PackageBinding packageBinding = this.binding.getPackage();
+				buffer = new StringBuffer();
+				if (packageBinding != null && packageBinding.compoundName != CharOperation.NO_CHAR_CHAR) {
+					buffer.append(CharOperation.concatWith(packageBinding.compoundName, '.')).append('.');
+				}
+				buffer.append(getName());
+				return String.valueOf(buffer);
 		}
-		buffer.append(getName());
-
-		return String.valueOf(buffer);
 	}
 
 	/*
 	 * @see ITypeBinding#getSuperclass()
 	 */
 	public ITypeBinding getSuperclass() {
-		if (this.binding == null || this.binding.isArrayType() || this.binding.isBaseType() || this.binding.isInterface()) {
+		if (this.binding == null) 
 			return null;
+		switch (this.binding.kind()) {
+			case Binding.ARRAY_TYPE :
+			case Binding.BASE_TYPE :
+				return null;
+			default:
+				// no superclass for interface types (interface | annotation type)
+				if (this.binding.isInterface())
+					return null;
 		}
-		ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
 		ReferenceBinding superclass = null;
 		try {
-			superclass = referenceBinding.superclass();
+			superclass = ((ReferenceBinding)this.binding).superclass();
 		} catch (RuntimeException e) {
 			/* in case a method cannot be resolvable due to missing jars on the classpath
 			 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
@@ -706,6 +814,18 @@
 		}
 		return NO_TYPE_BINDINGS;
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.dom.ITypeBinding#getWildcard()
+	 * @since 3.1
+	 */
+	public ITypeBinding getWildcard() {
+		if (this.binding instanceof CaptureBinding) {
+			CaptureBinding captureBinding = (CaptureBinding) this.binding;
+			return this.resolver.getTypeBinding(captureBinding.wildcard);
+		}
+		return null;
+	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isGenericType()
@@ -713,6 +833,9 @@
 	 */
 	public boolean isGenericType() {
 		// equivalent to return getTypeParameters().length > 0;
+		if (isRawType()) {
+			return false;
+		}
 		TypeVariableBinding[] typeVariableBindings = this.binding.typeVariables();
 		return (typeVariableBindings != null && typeVariableBindings.length > 0);
 	}
@@ -728,7 +851,7 @@
 	 * @see ITypeBinding#isAnonymous()
 	 */
 	public boolean isAnonymous() {
-		if (isClass() || binding.isInterface() || isEnum()) {
+		if (isClass() || isInterface() || isEnum()) {
 			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
 			return referenceBinding.isAnonymousType();
 		}
@@ -754,6 +877,13 @@
 	}
 	
 	/* (non-Javadoc)
+	 * @see ITypeBinding#isCapture()
+	 */
+	public boolean isCapture() {
+		return this.binding.isCapture();
+	}
+
+	/* (non-Javadoc)
 	 * @see ITypeBinding#isCastCompatible(ITypeBinding)
 	 */
 	public boolean isCastCompatible(ITypeBinding type) {
@@ -819,7 +949,18 @@
 	public boolean isFromSource() {
 		if (isClass() || isInterface() || isEnum()) {
 			ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
-			return !referenceBinding.isBinaryBinding();
+			if (referenceBinding.isRawType()) {
+				return !((RawTypeBinding) referenceBinding).type.isBinaryBinding();
+			} else if (referenceBinding.isParameterizedType()) {
+				ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) referenceBinding;
+				org.eclipse.jdt.internal.compiler.lookup.TypeBinding erasure = parameterizedTypeBinding.erasure();
+				if (erasure instanceof ReferenceBinding) {
+					return !((ReferenceBinding) erasure).isBinaryBinding();
+				}
+				return false;
+			} else {
+				return !referenceBinding.isBinaryBinding();
+			}
 		}
 		return false;
 	}
@@ -925,14 +1066,14 @@
 	 * @see ITypeBinding#isTypeVariable()
 	 */
 	public boolean isTypeVariable() {
-		return this.binding.isTypeVariable();
+		return this.binding.isTypeVariable() && !this.binding.isCapture();
 	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.core.dom.ITypeBinding#isUpperbound()
 	 */
 	public boolean isUpperbound() {
-		return this.binding.isWildcard() && ((WildcardBinding) this.binding).kind == Wildcard.EXTENDS;
+		return this.binding.isWildcard() && ((WildcardBinding) this.binding).boundKind == Wildcard.EXTENDS;
 	}
 
 	/* (non-Javadoc)
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java
index 86b1da9..f43cc93 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -78,13 +78,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-    // TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		internalModifiersPropertyFactory(TypeDeclaration.class);
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		internalModifiers2PropertyFactory(TypeDeclaration.class);
@@ -107,7 +106,6 @@
 	 * The "superclass" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #SUPERCLASS_TYPE_PROPERTY} in the JLS3 API.
 	public static final ChildPropertyDescriptor SUPERCLASS_PROPERTY = 
 		new ChildPropertyDescriptor(TypeDeclaration.class, "superclass", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
 
@@ -115,27 +113,26 @@
 	 * The "superInterfaces" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #SUPER_INTERFACE_TYPES_PROPERTY} in the JLS3 API.
 	public static final ChildListPropertyDescriptor SUPER_INTERFACES_PROPERTY = 
 		new ChildListPropertyDescriptor(TypeDeclaration.class, "superInterfaces", Name.class, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "superclassType" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildPropertyDescriptor SUPERCLASS_TYPE_PROPERTY = 
 		new ChildPropertyDescriptor(TypeDeclaration.class, "superclassType", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "superInterfaceTypes" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor SUPER_INTERFACE_TYPES_PROPERTY = 
 		new ChildListPropertyDescriptor(TypeDeclaration.class, "superInterfaceTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
 	
 	/**
 	 * The "typeParameters" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY = 
 		new ChildListPropertyDescriptor(TypeDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -159,7 +156,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -200,7 +197,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -217,7 +214,7 @@
 	 * The type paramters (element type: <code>TypeParameter</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList typeParameters = null;
 
@@ -240,7 +237,7 @@
 	 * The optional superclass type; <code>null</code> if none.
 	 * Defaults to none. Note that this field is not used for
 	 * interface declarations. Null in JLS2. Added in JLS3.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private Type optionalSuperclassType = null;
 
@@ -248,7 +245,7 @@
 	 * The superinterface types (element type: <code>Type</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList superInterfaceTypes = null;
 
@@ -268,7 +265,7 @@
 	 */
 	TypeDeclaration(AST ast) {
 		super(ast);
-		if (ast.apiLevel == AST.JLS2) {
+		if (ast.apiLevel == AST.JLS2_INTERNAL) {
 			this.superInterfaceNames = new ASTNode.NodeList(SUPER_INTERFACES_PROPERTY);
 		}
 		if (ast.apiLevel >= AST.JLS3) {
@@ -293,7 +290,7 @@
 			if (get) {
 				return getModifiers();
 			} else {
-				setModifiers(value);
+				internalSetModifiers(value);
 				return 0;
 			}
 		}
@@ -431,8 +428,8 @@
 		result.setSourceRange(this.getStartPosition(), this.getLength());
 		result.setJavadoc(
 			(Javadoc) ASTNode.copySubtree(target, getJavadoc()));
-		if (this.ast.apiLevel == AST.JLS2) {
-			result.setModifiers(getModifiers());
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
+			result.internalSetModifiers(getModifiers());
 			result.setSuperclass(
 					(Name) ASTNode.copySubtree(target, getSuperclass()));
 			result.superInterfaces().addAll(
@@ -469,7 +466,7 @@
 		boolean visitChildren = visitor.visit(this);
 		if (visitChildren) {
 			// visit children in normal left to right reading order
-			if (this.ast.apiLevel == AST.JLS2) {
+			if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 				acceptChild(visitor, getJavadoc());
 				acceptChild(visitor, getName());
 				acceptChild(visitor, getSuperclass());
@@ -517,18 +514,12 @@
 	/**
 	 * Returns the live ordered list of type parameters of this type 
 	 * declaration (added in JLS3 API). This list is non-empty for parameterized types.
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of type parameters
 	 *    (element type: <code>TypeParameter</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List typeParameters() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -551,10 +542,21 @@
 	 *    there is none
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by
+	 * {@link #getSuperclassType()}, which returns a <code>Type</code>
+	 * instead of a <code>Name</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>getSuperclassType</code>, which returns a <code>Type</code> instead of a <code>Name</code>.
 	public Name getSuperclass() {
-	    supportedOnlyIn2();
+		return internalGetSuperclass();
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final Name internalGetSuperclass() {
+		supportedOnlyIn2();
 		return this.optionalSuperclassName;
 	}
 
@@ -571,7 +573,7 @@
 	*    there is none
 	* @exception UnsupportedOperationException if this operation is used in
 	* a JLS2 AST
-	* @since 3.0
+	* @since 3.1
 	*/ 
 	public Type getSuperclassType() {
 	    unsupportedIn2();
@@ -596,9 +598,20 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link #setSuperclassType(Type)}, which expects a
+	 * <code>Type</code> instead of a <code>Name</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>setType</code>, which expects a <code>Type</code> instead of a <code>Name</code>.
 	public void setSuperclass(Name superclassName) {
+		internalSetSuperclass(superclassName);
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetSuperclass(Name superclassName) {
 	    supportedOnlyIn2();
 		ASTNode oldChild = this.optionalSuperclassName;
 		preReplaceChild(oldChild, superclassName, SUPERCLASS_PROPERTY);
@@ -623,7 +636,7 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public void setSuperclassType(Type superclassType) {
 	    unsupportedIn2();
@@ -644,9 +657,19 @@
 	 *    (element type: <code>Name</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link #superInterfaceTypes()}.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>superInterfaceTypes()</code>
 	public List superInterfaces() {
+		return internalSuperInterfaces();
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final List internalSuperInterfaces() {
 		// more efficient than just calling supportedOnlyIn2() to check
 		if (this.superInterfaceNames == null) {
 			supportedOnlyIn2();
@@ -664,7 +687,7 @@
 	 *    (element type: <code>Type</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List superInterfaceTypes() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -777,26 +800,6 @@
 	/* (omit javadoc for this method)
 	 * Method declared on ASTNode.
 	 */
-	void appendDebugString(StringBuffer buffer) {
-		buffer.append("TypeDeclaration["); //$NON-NLS-1$
-		buffer.append(isInterface()
-		   ? "interface " //$NON-NLS-1$
-		   : "class "); //$NON-NLS-2$//$NON-NLS-1$
-		buffer.append(getName().getIdentifier());
-		buffer.append(" "); //$NON-NLS-1$
-		for (Iterator it = bodyDeclarations().iterator(); it.hasNext();) {
-			BodyDeclaration d = (BodyDeclaration) it.next();
-			d.appendDebugString(buffer);
-			if (it.hasNext()) {
-				buffer.append(";"); //$NON-NLS-1$
-			}
-		}
-		buffer.append("]"); //$NON-NLS-1$
-	}
-		
-	/* (omit javadoc for this method)
-	 * Method declared on ASTNode.
-	 */
 	int memSize() {
 		return super.memSize() + 6 * 4;
 	}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java
index bd95600..6230220 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -43,13 +43,12 @@
 	 * The "typeDeclaration" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #DECLARATION_PROPERTY} in the JLS3 API.
 	public static final ChildPropertyDescriptor TYPE_DECLARATION_PROPERTY = 
 		new ChildPropertyDescriptor(TypeDeclarationStatement.class, "typeDeclaration", TypeDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "declaration" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildPropertyDescriptor DECLARATION_PROPERTY = 
 		new ChildPropertyDescriptor(TypeDeclarationStatement.class, "declaration", AbstractTypeDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
@@ -66,7 +65,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -94,7 +93,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -197,7 +196,7 @@
 	 * statement (added in JLS3 API).
 	 * 
 	 * @return the type declaration node
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public AbstractTypeDeclaration getDeclaration() {
 		if (this.typeDecl == null) {
@@ -224,7 +223,7 @@
 	 * <li>the node already has a parent</li>
 	 * <li>a cycle in would be created</li>
 	 * </ul>
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public void setDeclaration(AbstractTypeDeclaration decl) {
 		if (decl == null) {
@@ -245,10 +244,21 @@
 	 * @return the type declaration node
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link #getDeclaration()}, which returns <code>AbstractTypeDeclaration</code>
+	 * instead of <code>TypeDeclaration</code>.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>getDeclaration</code>, which returns <code>AbstractTypeDeclaration</code> instead of <code>TypeDeclaration</code>.
 	public TypeDeclaration getTypeDeclaration() {
-	    supportedOnlyIn2();
+		return internalGetTypeDeclaration();
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final TypeDeclaration internalGetTypeDeclaration() {
+		supportedOnlyIn2();
 		return (TypeDeclaration) getDeclaration();
 	}
 		
@@ -265,9 +275,21 @@
 	 * </ul>
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
+     * @deprecated In the JLS3 API, this method is replaced by 
+     * {@link #setDeclaration(AbstractTypeDeclaration)} which takes
+     * <code>AbstractTypeDeclaration</code> instead of
+     * <code>TypeDeclaration</code>.
 	 */ 
-    // TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>setDeclaration</code> which takes <code>AbstractTypeDeclaration</code> instead of <code>TypeDeclaration</code>.
 	public void setTypeDeclaration(TypeDeclaration decl) {
+		internalSetTypeDeclaration(decl);
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetTypeDeclaration(TypeDeclaration decl) {
 	    supportedOnlyIn2();
 		// forward to non-deprecated replacement method
 		setDeclaration(decl);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java
index b149f8e..275c51a 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeLiteral.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java
index 6247d14..c707393 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2004 IBM Corporation and others.
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,27 +20,19 @@
  * TypeParameter:
  *    TypeVariable [ <b>extends</b> Type { <b>&</b> Type } ]
  * </pre>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class TypeParameter extends ASTNode {
 	
 	/**
 	 * The "name" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor NAME_PROPERTY = 
 		new ChildPropertyDescriptor(TypeParameter.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "typeBounds" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildListPropertyDescriptor TYPE_BOUNDS_PROPERTY = 
 		new ChildListPropertyDescriptor(TypeParameter.class, "typeBounds", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
@@ -69,7 +61,6 @@
 
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
@@ -205,9 +196,8 @@
 	 * 
 	 * @return the binding, or <code>null</code> if the binding cannot be 
 	 *    resolved
-	 * @since 3.1
 	 */	
-	public final IBinding resolveBinding() {
+	public final ITypeBinding resolveBinding() {
 		return this.ast.getBindingResolver().resolveTypeParameter(this);
 	}
 	
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
index b533b0f..17532f0 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableBinding.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,6 +14,7 @@
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.util.IModifierConstants;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
@@ -109,11 +110,25 @@
 	}
 
 	/*
+	 * @see IVariableBinding#getVariableDeclaration()
+	 * @since 3.1
+	 */
+	public IVariableBinding getVariableDeclaration() {
+		if (this.isField()) {
+			FieldBinding fieldBinding = (FieldBinding) this.binding;
+			return this.resolver.getVariableBinding(fieldBinding.original());
+		}
+		return this;
+	}
+	
+	/*
 	 * @see IBinding#getJavaElement()
 	 */
 	public IJavaElement getJavaElement() {
 		if (isField()) {
 			// field
+			FieldBinding fieldBinding = (FieldBinding) this.binding;
+			if (fieldBinding.declaringClass == null) return null; // arraylength
 			IType declaringType = (IType) getDeclaringClass().getJavaElement();
 			if (declaringType == null) return null;
 			return declaringType.getField(getName());
@@ -260,6 +275,14 @@
 	}
 
 	/*
+	 * @see IVariableBinding#isEnumConstant()
+	 * @since 3.1
+	 */
+	public boolean isEnumConstant() {
+		return (this.binding.modifiers & IConstants.AccEnum) != 0;
+	}
+
+	/*
 	 * @see IBinding#isSynthetic()
 	 */
 	public boolean isSynthetic() {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java
index 06281ea..673d2b2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java
index e6b1a40..d931eac 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -47,13 +47,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		new SimplePropertyDescriptor(VariableDeclarationExpression.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		new ChildListPropertyDescriptor(VariableDeclarationExpression.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
@@ -84,7 +83,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -116,7 +115,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -235,7 +234,7 @@
 		VariableDeclarationExpression result = 
 			new VariableDeclarationExpression(target);
 		result.setSourceRange(this.getStartPosition(), this.getLength());
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			result.setModifiers(getModifiers());
 		}
 		if (this.ast.apiLevel >= AST.JLS3) {
@@ -279,18 +278,12 @@
 	 * Note that the final modifier is the only meaningful modifier for local
 	 * variable declarations.
 	 * </p>
-	 * <p>
-	 * Note: This API element is only needed for dealing with Java code that uses
-	 * new language features of J2SE 1.5. It is included in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
-	 * may change slightly before reaching its final form.
-	 * </p>
 	 * 
 	 * @return the live list of modifiers and annotations
 	 *    (element type: <code>IExtendedModifier</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List modifiers() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -341,12 +334,22 @@
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
 	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>modifiers()</code> which contains a list of a <code>Modifier</code> nodes.
 	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
 	    supportedOnlyIn2();
 		preValueChange(MODIFIERS_PROPERTY);
-		this.modifierFlags = modifiers;
+		this.modifierFlags = pmodifiers;
 		postValueChange(MODIFIERS_PROPERTY);
 	}
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java
index 80d11af..be35038 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationFragment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java
index 1c4c2dd..1cdcb79 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -50,13 +50,12 @@
 	 * The "modifiers" structural property of this node type (JLS2 API only).
 	 * @since 3.0
 	 */
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated Replaced by {@link #MODIFIERS2_PROPERTY} in the JLS3 API.
 	public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
 		new SimplePropertyDescriptor(VariableDeclarationStatement.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
 	
 	/**
 	 * The "modifiers" structural property of this node type (added in JLS3 API).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
 		new ChildListPropertyDescriptor(VariableDeclarationStatement.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
@@ -87,7 +86,7 @@
 	 * A list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private static final List PROPERTY_DESCRIPTORS_3_0;
 	
@@ -119,7 +118,7 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == AST.JLS2_INTERNAL) {
 			return PROPERTY_DESCRIPTORS_2_0;
 		} else {
 			return PROPERTY_DESCRIPTORS_3_0;
@@ -130,7 +129,7 @@
 	 * The extended modifiers (element type: <code>IExtendedModifier</code>). 
 	 * Null in JLS2. Added in JLS3; defaults to an empty list
 	 * (see constructor).
-	 * @since 3.0
+	 * @since 3.1
 	 */
 	private ASTNode.NodeList modifiers = null;
 	
@@ -239,7 +238,7 @@
 			new VariableDeclarationStatement(target);
 		result.setSourceRange(this.getStartPosition(), this.getLength());
 		result.copyLeadingComment(this);
-		if (this.ast.apiLevel == AST.JLS2) {
+		if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
 			result.setModifiers(getModifiers());
 		}
 		if (this.ast.apiLevel >= AST.JLS3) {
@@ -287,7 +286,7 @@
 	 *    (element type: <code>IExtendedModifier</code>)
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * a JLS2 AST
-	 * @since 3.0
+	 * @since 3.1
 	 */ 
 	public List modifiers() {
 		// more efficient than just calling unsupportedIn2() to check
@@ -338,12 +337,22 @@
 	 * @exception UnsupportedOperationException if this operation is used in
 	 * an AST later than JLS2
 	 * @see Modifier
+	 * @deprecated In the JLS3 API, this method is replaced by 
+	 * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
 	 */ 
-	// TODO (jeem) When JLS3 support is complete (post 3.0) - deprecated In the JLS3 API, this method is replaced by <code>modifiers()</code> which contains a list of a <code>Modifier</code> nodes.
 	public void setModifiers(int modifiers) {
+		internalSetModifiers(modifiers);
+	}
+	
+	/**
+	 * Internal synonym for deprecated method. Used to avoid
+	 * deprecation warnings.
+	 * @since 3.1
+	 */
+	/*package*/ final void internalSetModifiers(int pmodifiers) {
 	    supportedOnlyIn2();
 		preValueChange(MODIFIERS_PROPERTY);
-		this.modifierFlags = modifiers;
+		this.modifierFlags = pmodifiers;
 		postValueChange(MODIFIERS_PROPERTY);
 	}
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java
index e6f7694..d00d376 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WhileStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java
index 8a33583..3c78dfc 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/WildcardType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2004 IBM Corporation and others.
+ * Copyright (c) 2003, 2005 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,27 +25,19 @@
  * it is nonsense if a wildcard type node appears anywhere other than as an
  * argument of a <code>ParameterizedType</code> node.
  * </p>
- * <p>
- * Note: This API element is only needed for dealing with Java code that uses
- * new language features of J2SE 1.5. It is included in anticipation of J2SE
- * 1.5 support, which is planned for the next release of Eclipse after 3.0, and
- * may change slightly before reaching its final form.
- * </p>
  * 
- * @since 3.0
+ * @since 3.1
  */
 public class WildcardType extends Type {
 	
 	/**
 	 * The "bound" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final ChildPropertyDescriptor BOUND_PROPERTY = 
 		new ChildPropertyDescriptor(WildcardType.class, "bound", Type.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
 	 * The "upperBound" structural property of this node type.
-	 * @since 3.0
 	 */
 	public static final SimplePropertyDescriptor UPPER_BOUND_PROPERTY = 
 		new SimplePropertyDescriptor(WildcardType.class, "upperBound", boolean.class, MANDATORY); //$NON-NLS-1$
@@ -74,7 +66,6 @@
 
 	 * @return a list of property descriptors (element type: 
 	 * {@link StructuralPropertyDescriptor})
-	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
 		return PROPERTY_DESCRIPTORS;
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
index 1c56637..0c5e848 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ASTRewrite.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,7 +25,6 @@
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.Block;
 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
-import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
 
 import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteAnalyzer;
@@ -52,7 +51,7 @@
  * </p>
  * <pre>
  * Document doc = new Document("import java.util.List;\nclass X {}\n");
- * ASTParser parser = ASTParser.newParser(AST.JLS2);
+ * ASTParser parser = ASTParser.newParser(AST.JLS3);
  * parser.setSource(doc.get().toCharArray());
  * CompilationUnit cu = (CompilationUnit) parser.createAST(null);
  * AST ast = cu.getAST();
@@ -85,6 +84,13 @@
 	private final NodeInfoStore nodeStore;
 	
 	/**
+	 * Target source range computer; null means uninitialized;
+	 * lazy initialized to <code>new TargetSourceRangeComputer()</code>.
+	 * @since 3.1
+	 */
+	private TargetSourceRangeComputer targetSourceRangeComputer = null;
+	
+	/**
 	 * Creates a new instance for describing manipulations of
 	 * the given AST.
 	 * 
@@ -140,6 +146,11 @@
 	 * edits to the given document containing the original source
 	 * code. The document itself is not modified.
 	 * <p>
+	 * For nodes in the original that are being replaced or deleted,
+	 * this rewriter computes the adjusted source ranges
+	 * by calling <code>getTargetSourceRangeComputer().computeSourceRange(node)</code>.
+	 * </p>
+	 * <p>
 	 * Calling this methods does not discard the modifications
 	 * on record. Subsequence modifications are added to the ones
 	 * already on record. If this method is called again later,
@@ -169,8 +180,7 @@
 			
 			getRewriteEventStore().markMovedNodesRemoved();
 
-			CompilationUnit astRoot= (CompilationUnit) rootNode.getRoot();
-			ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, astRoot, result, this.eventStore, this.nodeStore, options);
+			ASTRewriteAnalyzer visitor= new ASTRewriteAnalyzer(document, result, this.eventStore, this.nodeStore, options, getExtendedSourceRangeComputer());
 			rootNode.accept(visitor); // throws IllegalArgumentException
 		}
 		return result;
@@ -499,6 +509,35 @@
 	public final ASTNode createMoveTarget(ASTNode node) {
 		return createTargetNode(node, true);
 	}	
+
+	/**
+	 * Returns the extended source range computer for this AST rewriter.
+	 * The default value is a <code>new ExtendedSourceRangeComputer()</code>.
+	 * 
+	 * @return an extended source range computer
+	 * @since 3.1
+	 */
+	public final TargetSourceRangeComputer getExtendedSourceRangeComputer() {
+		if (this.targetSourceRangeComputer == null) {
+			// lazy initialize
+			this.targetSourceRangeComputer = new TargetSourceRangeComputer(); 
+		}
+		return this.targetSourceRangeComputer;
+	}
+	
+	/**
+	 * Sets a custom target source range computer for this AST rewriter. This is advanced feature to modify how
+	 * comments are assotiated with nodes, which should be done only in special cases.
+	 * 
+	 * @param computer a target source range computer,
+	 * or <code>null</code> to restore the default value of
+	 * <code>new TargetSourceRangeComputer()</code>
+	 * @since 3.1
+	 */
+	public final void setTargetSourceRangeComputer(TargetSourceRangeComputer computer) {
+		// if computer==null, rely on lazy init code in getTargetSourceRangeComputer()
+		this.targetSourceRangeComputer = computer;
+	}
 	
 	/**
 	 * Returns a string suitable for debugging purposes (only).
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java
index 55a0ee1..f371b47 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ITrackedNodePosition.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
index 7f848f2..540603b 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/ListRewrite.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -57,6 +57,28 @@
 	}
 	
 	/**
+	 * Returns the parent of the list for which this list rewriter was created.
+
+	 * @return the node that contains the list for which this list rewriter was created
+	 * @see #getLocationInParent()
+	 * @since 3.1
+	 */
+	public ASTNode getParent() {
+		return this.parent;
+	}
+	
+	/**
+	 * Returns the property of the parent node for which this list rewriter was created. 
+	 * 
+	 * @return the property of the parent node for which this list rewriter was created
+	 * @see #getParent()
+	 * @since 3.1
+	 */
+	public StructuralPropertyDescriptor getLocationInParent() {
+		return this.childProperty;
+	}
+	
+	/**
 	 * Removes the given node from its parent's list property in the rewriter.
 	 * The node must be contained in the list.
 	 * The AST itself is not actually modified in any way; rather, the rewriter
@@ -307,6 +329,30 @@
 		}
 	}
 	
+	/**
+	 * Creates and returns a placeholder node for a move of a range of nodes of the
+	 * current list.
+	 * The placeholder node can either be inserted as new or used to replace an
+	 * existing node. When the document is rewritten, a copy of the source code 
+	 * for the given node range is inserted into the output document at the position
+	 * corresponding to the placeholder (indentation is adjusted).
+	 * 
+	 * @param first the node that starts the range
+	 * @param last the node that ends the range
+	 * @return the new placeholder node
+	 * @throws IllegalArgumentException if the node is null, or if the node
+	 * is not part of this rewriter's AST
+	 * 
+	 * @since 3.1
+	 */
+	public final ASTNode createMoveTarget(ASTNode first, ASTNode last) {
+		if (first == last) {
+			return this.rewriter.createMoveTarget(first);
+		} else {
+			return createTargetNode(first, last, true);
+		}
+	}
+	
 	/*
 	 * Heuristic to decide if a inserted node is bound to previous or the next sibling. 
 	 */
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
new file mode 100644
index 0000000..2c24289
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/rewrite/TargetSourceRangeComputer.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.dom.rewrite;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+/**
+ * An object for computing adjusted source ranges for AST nodes
+ * that are being replaced or deleted.
+ * <p>
+ * For example, a refactoring like inline method may choose to replace
+ * calls to the method but leave intact any comments immediately preceding
+ * the calls. On the other hand, a refactoring like extract method may choose
+ * to extract not only the nodes for the selected code but also any
+ * comments preceding or following them.
+ * </p>
+ * <p>
+ * Clients should subclass if they need to influence the 
+ * the source range to be affected when replacing or deleting a particular node.
+ * An instance of the subclass should be registered with
+ * {@link ASTRewrite#setTargetSourceRangeComputer(TargetSourceRangeComputer)}.
+ * During a call to {@link ASTRewrite#rewriteAST(org.eclipse.jface.text.IDocument, java.util.Map)},
+ * the {@link #computeSourceRange(ASTNode)} method on this object will be
+ * used to compute the source range for a node being deleted or replaced.
+ * </p>
+ * 
+ * @since 3.1
+ */
+public class TargetSourceRangeComputer {
+	
+	/**
+	 * Reified source range. Instances are &quot;value&quot; object
+	 * (cannot be modified).
+	 * 
+	 * @since 3.1
+	 */
+	public static final class SourceRange {
+		/**
+		 * 0-based character index, or <code>-1</code>
+		 * if no source position information is known.
+		 */
+		private int startPosition;
+		
+		/**
+		 * (possibly 0) length, or <code>0</code>
+		 * if no source position information is known.
+		 */
+		private int length;
+		
+		/**
+		 * Creates a new source range.
+		 * 
+		 * @param startPosition the 0-based character index, or <code>-1</code>
+		 *    if no source position information is known
+		 * @param length the (possibly 0) length, or <code>0</code>
+		 *    if no source position information is known
+		 */
+		public SourceRange(int startPosition, int length) {
+			this.startPosition = startPosition;
+			this.length = length;
+		}
+		
+		/**
+		 * Returns the start position.
+		 * 
+		 * @return the 0-based character index, or <code>-1</code>
+		 *    if no source position information is known
+		 */
+		public int getStartPosition() {
+			return this.startPosition;
+		}
+
+		/**
+		 * Returns the source length.
+		 * 
+		 * @return a (possibly 0) length, or <code>0</code>
+		 *    if no source position information is known
+		 */
+		public int getLength() {
+			return this.length;
+		}
+	}
+
+	/**
+	 * Creates a new target source range computer.
+	 */
+	public TargetSourceRangeComputer() {
+		// do nothing
+	}
+
+	/**
+	 * Returns the target source range of the given node. Unlike
+	 * {@link ASTNode#getStartPosition()} and {@link ASTNode#getLength()},
+	 * the extended source range may include comments and whitespace
+	 * immediately before or after the normal source range for the node.
+	 * <p>
+	 * The returned source ranges must satisfy the following conditions:
+	 * <dl>
+	 * <li>no two source ranges in an AST may be overlapping</li>
+	 * <li>a source range of a parent node must fully cover the source ranges of its children</li>
+	 * 	</dl>
+	 * 	</p>
+	 * <p>
+	 * The default implementation uses
+	 * {@link CompilationUnit#getExtendedStartPosition(ASTNode)}
+	 * and {@link CompilationUnit#getExtendedLength(ASTNode)}
+	 * to compute the target source range. Clients may override or
+	 * extend this method to expand or contract the source range of the
+	 * given node. The resulting source range must cover at least the
+	 * original source range of the node.
+	 * </p>
+	 * 
+	 * @param node the node with a known source range in the compilation unit
+	 * being rewritten
+	 * @return the exact source range in the compilation unit being rewritten
+	 * that should be replaced (or deleted)
+	 */
+	public SourceRange computeSourceRange(ASTNode node) {
+		CompilationUnit cu = (CompilationUnit) node.getRoot();
+		return new SourceRange(
+				cu.getExtendedStartPosition(node),
+				cu.getExtendedLength(node));
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index cb1e8ea..81f09de 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -41,6 +41,8 @@
 import org.eclipse.jdt.core.compiler.ITerminalSymbols;
 
 import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
+import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer.SourceRange;
 
 import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.BlockContext;
 import org.eclipse.jdt.internal.core.dom.rewrite.ASTRewriteFormatter.NodeMarker;
@@ -61,6 +63,13 @@
  */
 public final class ASTRewriteAnalyzer extends ASTVisitor {
 	
+	/**
+	 * Internal synonynm for deprecated constant AST.JLS2
+	 * to alleviate deprecation warnings.
+	 * @deprecated
+	 */
+	/*package*/ static final int JLS2_INTERNAL = AST.JLS2;
+	
 	TextEdit currentEdit;
 	final RewriteEventStore eventStore; // used from inner classes
 	
@@ -72,13 +81,12 @@
 	private final IDocument document;
 	private final ASTRewriteFormatter formatter;
 	private final NodeInfoStore nodeInfos;
-	private final CompilationUnit astRoot;
+	private final TargetSourceRangeComputer extendedSourceRangeComputer;
 	
 	/*
 	 * Constructor for ASTRewriteAnalyzer.
 	 */
-	public ASTRewriteAnalyzer(IDocument document, CompilationUnit astRoot, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, Map options) {
-		this.astRoot= astRoot;
+	public ASTRewriteAnalyzer(IDocument document, TextEdit rootEdit, RewriteEventStore eventStore, NodeInfoStore nodeInfos, Map options, TargetSourceRangeComputer extendedSourceRangeComputer) {
 		this.eventStore= eventStore;
 		this.document= document;
 		this.nodeInfos= nodeInfos;
@@ -86,8 +94,10 @@
 		this.currentEdit= rootEdit;
 		this.sourceCopyInfoToEdit= new IdentityHashMap();
 		this.sourceCopyEndNodes= new Stack();
+
+		this.formatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, TextUtilities.getDefaultLineDelimiter(document));
 		
-		this.formatter= new ASTRewriteFormatter(nodeInfos, eventStore, options, getLineDelimiter());
+		this.extendedSourceRangeComputer = extendedSourceRangeComputer;
 	}
 		
 	final TokenScanner getScanner() {
@@ -103,23 +113,42 @@
 		return this.document;
 	}
 	
-	final int getExtendedOffset(ASTNode node) {
-		return this.astRoot.getExtendedStartPosition(node);
+	/**
+	 * Returns the extended source range computer for this AST rewriter.
+	 * 
+	 * @return an extended source range computer (never null)
+	 * @since 3.1
+	 */
+	private TargetSourceRangeComputer getExtendedSourceRangeComputer() {
+		return this.extendedSourceRangeComputer;
 	}
 	
-	final int getExtendedLength(ASTNode node) {
-		return this.astRoot.getExtendedLength(node);
+	final SourceRange getExtendedRange(ASTNode node) {
+		return getExtendedSourceRangeComputer().computeSourceRange(node);
+	}
+	
+	final int getExtendedOffset(ASTNode node) {
+		return getExtendedSourceRangeComputer().computeSourceRange(node).getStartPosition();
 	}
 	
 	final int getExtendedEnd(ASTNode node) {
-		return this.astRoot.getExtendedStartPosition(node) + this.astRoot.getExtendedLength(node);
+		TargetSourceRangeComputer.SourceRange range =
+			getExtendedSourceRangeComputer().computeSourceRange(node);
+		return range.getStartPosition() + range.getLength();
 	}
 	
 	final TextEdit getCopySourceEdit(CopySourceInfo info) {
 		TextEdit edit= (TextEdit) this.sourceCopyInfoToEdit.get(info);
 		if (edit == null) {
-			int start= getExtendedOffset(info.getStartNode());
-			int end= getExtendedEnd(info.getEndNode());
+			int start, end;
+			if (info.getStartNode() == info.getEndNode()) {
+				SourceRange range= getExtendedRange(info.getStartNode());
+				start= range.getStartPosition();
+				end= start + range.getLength();
+			} else {
+				start= getExtendedOffset(info.getStartNode());
+				end= getExtendedEnd(info.getEndNode());
+			}
 			if (info.isMove) {
 				MoveSourceEdit moveSourceEdit= new MoveSourceEdit(start, end - start);
 				moveSourceEdit.setTargetEdit(new MoveTargetEdit(0));
@@ -191,7 +220,7 @@
 	}
 	
 	final String getLineDelimiter() {
-		return TextUtilities.getDefaultLineDelimiter(getDocument());
+		return this.formatter.lineDelimiter;
 	}
 	
 	final String createIndentString(int indent) {
@@ -202,7 +231,7 @@
 		try {
 			IRegion line= getDocument().getLineInformationOfOffset(pos);
 			String str= getDocument().get(line.getOffset(), line.getLength());
-			return Indents.getIndentString(str, this.formatter.getTabWidth());
+			return this.formatter.getIndentString(str);
 		} catch (BadLocationException e) {
 			return ""; //$NON-NLS-1$
 		}
@@ -238,10 +267,10 @@
 		TextEdit edit= doTextRemove(offset, len, editGroup);
 		if (edit != null) {
 			this.currentEdit= edit;
-			doVisit(node);
+			voidVisit(node);
 			this.currentEdit= edit.getParent();
 		} else {
-			doVisit(node);
+			voidVisit(node);
 		}
 	}
 	
@@ -283,6 +312,37 @@
 		}
 	}
 	
+	final void voidVisit(ASTNode node) {
+		node.accept(this);
+	}
+	
+	private final void voidVisit(ASTNode parent, StructuralPropertyDescriptor property) {
+		Object node= getOriginalValue(parent, property);
+		if (property.isChildProperty() && node != null) {
+			voidVisit((ASTNode) node);
+		} else if (property.isChildListProperty()) {
+			boolean hasRangeCopySources= this.eventStore.hasRangeCopySources(parent, property);
+			voidVisitList((List) node, hasRangeCopySources);
+		}
+	}
+	
+	private void voidVisitList(List list, boolean hasRangeCopySources) {
+		if (hasRangeCopySources) {
+			// list with copy source ranges
+			Stack nodeRangeEndStack= new Stack();
+			for (Iterator iter= list.iterator(); iter.hasNext();) {
+				ASTNode curr= ((ASTNode) iter.next());
+				doCopySourcePreVisit(this.eventStore.getRangeCopySources(curr), nodeRangeEndStack);
+				doVisit(curr);
+				doCopySourcePostVisit(curr, nodeRangeEndStack);
+			}
+		} else {
+			for (Iterator iter= list.iterator(); iter.hasNext();) {
+				doVisit(((ASTNode) iter.next()));
+			}
+		}
+	}
+	
 	private final boolean doVisitUnchangedChildren(ASTNode parent) {
 		List properties= parent.structuralPropertiesForType();
 		for (int i= 0; i < properties.size(); i++) {
@@ -290,12 +350,12 @@
 			if (property.isChildProperty()) {
 				ASTNode child= (ASTNode) parent.getStructuralProperty(property);
 				if (child != null) {
-					doVisit(child);
+					voidVisit(child);
 				}
 			} else if (property.isChildListProperty()) {
 				List list= (List) parent.getStructuralProperty(property);
 				boolean hasRangeCopySources= this.eventStore.hasRangeCopySources(parent, property);
-				doVisitList(list, 0, hasRangeCopySources);
+				voidVisitList(list, hasRangeCopySources);
 			}
 		}
 		return false;
@@ -312,24 +372,26 @@
 		}
 	}
 		
-	private final TextEdit doTextCopy(TextEdit sourceEdit, int destOffset, int sourceIndentLevel, String destIndentString, int tabWidth, TextEditGroup editGroup) {
+	private final TextEdit doTextCopy(TextEdit sourceEdit, int destOffset, int sourceIndentLevel, String destIndentString, TextEditGroup editGroup) {
 		TextEdit targetEdit;
+		SourceModifier modifier= new SourceModifier(sourceIndentLevel, destIndentString, this.formatter.tabWidth, this.formatter.indentWidth);
+		
 		if (sourceEdit instanceof MoveSourceEdit) {
 			MoveSourceEdit moveEdit= (MoveSourceEdit) sourceEdit;
-			moveEdit.setSourceModifier(new SourceModifier(sourceIndentLevel, destIndentString, tabWidth));
+			moveEdit.setSourceModifier(modifier);
 			
 			targetEdit= new MoveTargetEdit(destOffset, moveEdit);
 			addEdit(targetEdit);
 		} else {
 			CopySourceEdit copyEdit= (CopySourceEdit) sourceEdit;
-			copyEdit.setSourceModifier(new SourceModifier(sourceIndentLevel, destIndentString, tabWidth));
+			copyEdit.setSourceModifier(modifier);
 			
 			targetEdit= new CopyTargetEdit(destOffset, copyEdit);
 			addEdit(targetEdit);
 		}
 		
 		if (editGroup != null) {
-			addEditGroup(editGroup, targetEdit);
+			addEditGroup(editGroup, sourceEdit);
 			addEditGroup(editGroup, targetEdit);
 		}
 		return targetEdit;			
@@ -402,6 +464,7 @@
 		public final int rewriteList(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword) {
 			this.startPos= offset;
 			this.list= getEvent(parent, property).getChildren();
+			
 			initCopyRangeChecks(parent, property);
 			
 			int total= this.list.length;
@@ -413,9 +476,10 @@
 			
 			int lastNonInsert= -1;
 			int lastNonDelete= -1;
-		
+					
 			for (int i= 0; i < total; i++) {
 				int currMark= this.list[i].getChangeKind();
+				
 				if (currMark != RewriteEvent.INSERTED) {
 					lastNonInsert= i;
 					if (currPos == -1) {
@@ -511,7 +575,7 @@
 					} else { // is unchanged
 						ASTNode node= (ASTNode) currEvent.getOriginalValue();
 						checkForRangeStart(node);
-						doVisit(node);
+						voidVisit(node);
 						checkForRangeEnd(node);
 					}
 					if (i == lastNonInsert) { // last node or next nodes are all inserts
@@ -560,8 +624,9 @@
 		if (event != null && event.getChangeKind() == RewriteEvent.REPLACED) {
 			ASTNode node= (ASTNode) event.getOriginalValue();
 			TextEditGroup editGroup= getEditGroup(event);
-			int offset= getExtendedOffset(node);
-			int length= getExtendedLength(node);
+			SourceRange range= getExtendedRange(node);
+			int offset= range.getStartPosition();
+			int length= range.getLength();
 			doTextRemoveAndVisit(offset, length, node, editGroup);
 			doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup);
 			return offset + length;	
@@ -577,7 +642,7 @@
 					ASTNode node= (ASTNode) event.getNewValue();
 					TextEditGroup editGroup= getEditGroup(event);
 					int indent= getIndent(offset);
-					doTextInsert(offset, prefix.getPrefix(indent, getLineDelimiter()), editGroup);
+					doTextInsert(offset, prefix.getPrefix(indent), editGroup);
 					doTextInsert(offset, node, indent, true, editGroup);
 					return offset;
 				}
@@ -594,8 +659,9 @@
 				case RewriteEvent.REPLACED: {
 					ASTNode node= (ASTNode) event.getOriginalValue();
 					TextEditGroup editGroup= getEditGroup(event);
-					int nodeOffset= getExtendedOffset(node);
-					int nodeLen= getExtendedLength(node);
+					SourceRange range= getExtendedRange(node);
+					int nodeOffset= range.getStartPosition();
+					int nodeLen= range.getLength();
 					doTextRemoveAndVisit(nodeOffset, nodeLen, node, editGroup);
 					doTextInsert(nodeOffset, (ASTNode) event.getNewValue(), getIndent(offset), true, editGroup);
 					return nodeOffset + nodeLen;
@@ -635,7 +701,7 @@
 					ASTNode node= (ASTNode) event.getNewValue();
 					TextEditGroup editGroup= getEditGroup(event);
 					
-					String[] strings= context.getPrefixAndSuffix(indent, getLineDelimiter(), node, this.eventStore);
+					String[] strings= context.getPrefixAndSuffix(indent, node, this.eventStore);
 					
 					doTextInsert(offset, strings[0], editGroup);
 					doTextInsert(offset, node, indent, true, editGroup);
@@ -663,7 +729,7 @@
 					int nodeLen= endPos - offset; 
 					
 					ASTNode replacingNode= (ASTNode) event.getNewValue();
-					String[] strings= context.getPrefixAndSuffix(indent, getLineDelimiter(), replacingNode, this.eventStore);
+					String[] strings= context.getPrefixAndSuffix(indent, replacingNode, this.eventStore);
 					doTextRemoveAndVisit(offset, nodeLen, node, editGroup);
 					
 					String prefix= strings[0];
@@ -671,7 +737,7 @@
 					String lineInPrefix= getCurrentLine(prefix, prefix.length());
 					if (prefix.length() != lineInPrefix.length()) {
 						// prefix contains a new line: update the indent to the one used in the prefix
-						indent= Indents.computeIndent(lineInPrefix, this.formatter.getTabWidth());
+						indent= this.formatter.computeIndentUnits(lineInPrefix);
 					}
 					doTextInsert(offset, replacingNode, indent, true, editGroup);
 					doTextInsert(offset, strings[1], editGroup);
@@ -712,16 +778,32 @@
 				case RewriteEvent.REPLACED: {
 					ASTNode node= (ASTNode) event.getOriginalValue();
 					TextEditGroup editGroup= getEditGroup(event);
-					int offset= getExtendedOffset(node);
-					int length= getExtendedLength(node);
+					SourceRange range= getExtendedRange(node);
+					int offset= range.getStartPosition();
+					int length= range.getLength();
 					
 					doTextRemoveAndVisit(offset, length, node, editGroup);
 					doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(startPos), true, editGroup);
-					return offset + length;
+					try {
+						return getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, offset + length);
+					} catch (CoreException e) {
+						handleException(e);
+					}
+					break;
 				}
 			}
 		}
-		return doVisit(parent, property, startPos);
+		Object node= getOriginalValue(parent, property);
+		if (node == null) {
+			return startPos;
+		}
+		int pos= doVisit((ASTNode) node);
+		try {
+			return getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, pos);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return pos;
 	}	
 	
 	private class ParagraphListRewriter extends ListRewriter {
@@ -835,23 +917,28 @@
 		return listRewriter.rewriteList(parent, property, insertPos, leadString.toString());
 	}
 	
-	private int rewriteOptionalTypeParameters(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword) {
+	private int rewriteOptionalTypeParameters(ASTNode parent, StructuralPropertyDescriptor property, int offset, String keyword, boolean adjustOnNext) {
 		int pos= offset;
 		RewriteEvent event= getEvent(parent, property);
 		if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
 			RewriteEvent[] children= event.getChildren();
 			try {
-				boolean isAllRemoved= isAllOfKind(children, RewriteEvent.REMOVED);
+				boolean isAllInserted= isAllOfKind(children, RewriteEvent.INSERTED);
+				if (isAllInserted && adjustOnNext) {
+					pos= getScanner().getNextStartOffset(pos, false); // adjust on next element
+				}
+				boolean isAllRemoved= !isAllInserted && isAllOfKind(children, RewriteEvent.REMOVED);
 				if (isAllRemoved) { // all removed: set start to left bracket
 					pos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNameLESS, pos);
 				}
-				pos= new ListRewriter().rewriteList(parent, property, pos, keyword + String.valueOf('<'), ", "); //$NON-NLS-1$ //$NON-NLS-2$
-				if (isAllRemoved) { // all removed: remove right bracked
+				pos= new ListRewriter().rewriteList(parent, property, pos, String.valueOf('<'), ", "); //$NON-NLS-1$ //$NON-NLS-2$
+				if (isAllRemoved) { // all removed: remove right and space up to next element
 					int endPos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameGREATER, pos); // set pos to '>'
+					endPos= getScanner().getNextStartOffset(endPos, false);
 					doTextRemove(pos, endPos - pos, getEditGroup(children[children.length - 1]));
 					return endPos;
-				} else if (isAllOfKind(children, RewriteEvent.INSERTED)) {
-					doTextInsert(pos, String.valueOf('>'), getEditGroup(children[children.length - 1]));
+				} else if (isAllInserted) {
+					doTextInsert(pos, String.valueOf('>' + keyword), getEditGroup(children[children.length - 1]));
 					return pos;
 				}
 			} catch (CoreException e) {
@@ -897,7 +984,7 @@
 					ASTNode body= (ASTNode) event.getNewValue();
 					doTextRemove(startPos, endPos - startPos, editGroup);
 					int indent= getIndent(parent.getStartPosition());
-					String prefix= this.formatter.METHOD_BODY.getPrefix(indent, getLineDelimiter());
+					String prefix= this.formatter.METHOD_BODY.getPrefix(indent);
 					doTextInsert(startPos, prefix, editGroup); 
 					doTextInsert(startPos, body, indent, true, editGroup);
 					return;
@@ -919,7 +1006,7 @@
 				}
 			}
 		}
-		doVisit(parent, MethodDeclaration.BODY_PROPERTY, startPos);
+		voidVisit(parent, MethodDeclaration.BODY_PROPERTY);
 	}
 	
 	private int rewriteExtraDimensions(ASTNode parent, StructuralPropertyDescriptor property, int pos) {
@@ -975,7 +1062,7 @@
 		try {
 			IRegion line= getDocument().getLineInformationOfOffset(pos);
 			String str= getDocument().get(line.getOffset(), line.getLength());
-			return Indents.computeIndent(str, this.formatter.getTabWidth());
+			return this.formatter.computeIndentUnits(str);
 		} catch (BadLocationException e) {
 			return 0;
 		}
@@ -985,7 +1072,7 @@
 		ArrayList markers= new ArrayList();
 		String formatted= this.formatter.getFormattedResult(node, initialIndentLevel, markers);
 
-		int tabWidth= this.formatter.getTabWidth();
+		
 		int currPos= 0;
 		if (removeLeadingIndent) {
 			while (currPos < formatted.length() && Character.isWhitespace(formatted.charAt(currPos))) {
@@ -1019,16 +1106,16 @@
 				}
 				currPos= offset;
 			} else {
-				String destIndentString=  Indents.getIndentString(getCurrentLine(formatted, offset), tabWidth);
+				String destIndentString=  this.formatter.getIndentString(getCurrentLine(formatted, offset));
 				if (data instanceof CopyPlaceholderData) { // replace with a copy/move target
 					CopySourceInfo copySource= ((CopyPlaceholderData) data).copySource;
 					int srcIndentLevel= getIndent(copySource.getStartNode().getStartPosition());
 					TextEdit sourceEdit= getCopySourceEdit(copySource);
-					doTextCopy(sourceEdit, insertOffset, srcIndentLevel, destIndentString, tabWidth, editGroup);
+					doTextCopy(sourceEdit, insertOffset, srcIndentLevel, destIndentString, editGroup);
 					currPos= offset + curr.length; // continue to insert after the replaced string
 				} else if (data instanceof StringPlaceholderData) { // replace with a placeholder
 					String code= ((StringPlaceholderData) data).code;
-					String str= Indents.changeIndent(code, 0, tabWidth, destIndentString, getLineDelimiter()); 
+					String str= this.formatter.changeIndent(code, 0, destIndentString); 
 					doTextInsert(insertOffset, str, editGroup);
 					currPos= offset + curr.length; // continue to insert after the replaced string
 				}
@@ -1193,8 +1280,9 @@
 
 		TextEditGroup editGroup= this.eventStore.getTrackedNodeData(node);
 		if (editGroup != null) {
-			int offset= getExtendedOffset(node);
-			int length= getExtendedLength(node);
+			SourceRange range= getExtendedRange(node);
+			int offset= range.getStartPosition();
+			int length= range.getLength();
 			TextEdit edit= new RangeMarker(offset, length);
 			addEditGroup(editGroup, edit);
 			addEdit(edit);
@@ -1252,7 +1340,7 @@
 		
 		int pos= rewriteJavadoc(node, TypeDeclaration.JAVADOC_PROPERTY);
 		
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == JLS2_INTERNAL) {
 			rewriteModifiers(node, TypeDeclaration.MODIFIERS_PROPERTY, pos);
 		} else {
 			rewriteModifiers2(node, TypeDeclaration.MODIFIERS2_PROPERTY, pos);
@@ -1280,12 +1368,12 @@
 		pos= rewriteRequiredNode(node, TypeDeclaration.NAME_PROPERTY);
 		
 		if (apiLevel >= AST.JLS3) {
-			pos= rewriteOptionalTypeParameters(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " "); //$NON-NLS-1$
+			pos= rewriteOptionalTypeParameters(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, pos, "", false); //$NON-NLS-1$
 		}
 		
 		// superclass
 		if (!isInterface || invertType) {
-			ChildPropertyDescriptor superClassProperty= (apiLevel == AST.JLS2) ? TypeDeclaration.SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY;
+			ChildPropertyDescriptor superClassProperty= (apiLevel == JLS2_INTERNAL) ? TypeDeclaration.SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY;
 
 			RewriteEvent superClassEvent= getEvent(node, superClassProperty);
 			
@@ -1305,8 +1393,9 @@
 				}
 				case RewriteEvent.REPLACED: {
 					ASTNode superClass= (ASTNode) superClassEvent.getOriginalValue();
-					int offset= getExtendedOffset(superClass);
-					int length= getExtendedLength(superClass);
+					SourceRange range= getExtendedRange(superClass);
+					int offset= range.getStartPosition();
+					int length= range.getLength();
 					doTextRemoveAndVisit(offset, length, superClass, getEditGroup(superClassEvent));
 					doTextInsert(offset, (ASTNode) superClassEvent.getNewValue(), 0, false, getEditGroup(superClassEvent));
 					pos= offset + length;
@@ -1318,7 +1407,7 @@
 			}
 		}
 		// extended interfaces
-		ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == AST.JLS2) ? TypeDeclaration.SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY;
+		ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == JLS2_INTERNAL) ? TypeDeclaration.SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY;
 
 		RewriteEvent interfaceEvent= getEvent(node, superInterfaceProperty);
 		if (interfaceEvent == null || interfaceEvent.getChangeKind() == RewriteEvent.UNCHANGED) {
@@ -1358,7 +1447,7 @@
 	}
 
 	private void rewriteReturnType(MethodDeclaration node, boolean isConstructor, boolean isConstructorChange) {
-		ChildPropertyDescriptor property= (node.getAST().apiLevel() == AST.JLS2) ? MethodDeclaration.RETURN_TYPE_PROPERTY : MethodDeclaration.RETURN_TYPE2_PROPERTY;
+		ChildPropertyDescriptor property= (node.getAST().apiLevel() == JLS2_INTERNAL) ? MethodDeclaration.RETURN_TYPE_PROPERTY : MethodDeclaration.RETURN_TYPE2_PROPERTY;
 
 		// weakness in the AST: return type can exist, even if missing in source
 		ASTNode originalReturnType= (ASTNode) getOriginalValue(node, property);
@@ -1372,7 +1461,7 @@
 		if (isConstructorChange || !returnTypeExists && newReturnType != originalReturnType) {
 			// use the start offset of the method name to insert
 			ASTNode originalMethodName= (ASTNode) getOriginalValue(node, MethodDeclaration.NAME_PROPERTY);
-			int nextStart= getExtendedOffset(originalMethodName);
+			int nextStart= originalMethodName.getStartPosition(); // see bug 84049: can't use extended offset
 			TextEditGroup editGroup= getEditGroup(node, property);
 			if (isConstructor || !returnTypeExists) { // insert
 				doTextInsert(nextStart, newReturnType, getIndent(nextStart), true, editGroup);
@@ -1393,10 +1482,11 @@
 			return doVisitUnchangedChildren(node);
 		}
 		int pos= rewriteJavadoc(node, MethodDeclaration.JAVADOC_PROPERTY);
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteModifiers(node, MethodDeclaration.MODIFIERS_PROPERTY, pos);
 		} else {
-			rewriteModifiers2(node, MethodDeclaration.MODIFIERS2_PROPERTY, pos);
+			pos= rewriteModifiers2(node, MethodDeclaration.MODIFIERS2_PROPERTY, pos);
+			pos= rewriteOptionalTypeParameters(node, MethodDeclaration.TYPE_PARAMETERS_PROPERTY, pos, " ", true); //$NON-NLS-1$
 		}
 		
 		boolean isConstructorChange= isChanged(node, MethodDeclaration.CONSTRUCTOR_PROPERTY);
@@ -1524,14 +1614,15 @@
 			Type newType= replacingType.getElementType();
 			Type oldType= getElementType(arrayType);
 			if (!newType.equals(oldType)) {
-				int offset= getExtendedOffset(oldType);
-				int length= getExtendedLength(oldType);
+				SourceRange range= getExtendedRange(oldType);
+				int offset= range.getStartPosition();
+				int length= range.getLength();
 				doTextRemove(offset, length, editGroup);
 				doTextInsert(offset, newType, 0, false, editGroup);
 			}
 			nNewBrackets= replacingType.getDimensions(); // is replaced type
 		}
-		doVisit(arrayType);
+		voidVisit(arrayType);
 		
 
 		try {
@@ -1560,13 +1651,14 @@
 							doTextRemoveAndVisit(offset, endPos - offset, elem, editGroup);
 						} else if (changeKind == RewriteEvent.REPLACED) {
 							editGroup= getEditGroup(event);
-							int elemOffset= getExtendedOffset(elem);
-							int elemLength= getExtendedLength(elem);
+							SourceRange range= getExtendedRange(elem);
+							int elemOffset= range.getStartPosition();
+							int elemLength= range.getLength();
 							doTextRemoveAndVisit(elemOffset, elemLength, elem, editGroup);
 							doTextInsert(elemOffset, (ASTNode) event.getNewValue(), 0, false, editGroup);
 							nNewBrackets--;
 						} else {
-							doVisit(elem);
+							voidVisit(elem);
 							nNewBrackets--;
 						}
 						offset= endPos;
@@ -1748,18 +1840,18 @@
 		}
 		
 		int pos= rewriteOptionalQualifier(node, ClassInstanceCreation.EXPRESSION_PROPERTY, node.getStartPosition());
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			pos= rewriteRequiredNode(node, ClassInstanceCreation.NAME_PROPERTY);
 		} else {
 			if (isChanged(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY)) {
 				try {
 					pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNamenew, pos); //after 'new'
-					rewriteOptionalTypeParameters(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, pos, " "); //$NON-NLS-1$
+					rewriteOptionalTypeParameters(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, pos, " ", true); //$NON-NLS-1$
 				} catch (CoreException e) {
 					handleException(e);
 				}
 			} else {
-				doVisit(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, 0);
+				voidVisit(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY);
 			}
 			pos= rewriteRequiredNode(node, ClassInstanceCreation.TYPE_PROPERTY);
 		}
@@ -1772,7 +1864,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, ClassInstanceCreation.ARGUMENTS_PROPERTY, 0);
+			voidVisit(node, ClassInstanceCreation.ARGUMENTS_PROPERTY);
 		}
 		
 		int kind= getChangeKind(node, ClassInstanceCreation.ANONYMOUS_CLASS_DECLARATION_PROPERTY);
@@ -1812,7 +1904,7 @@
 		}
 		int pos= node.getStartPosition();
 		if (node.getAST().apiLevel() >= AST.JLS3) {
-			pos= rewriteOptionalTypeParameters(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, ""); //$NON-NLS-1$
+			pos= rewriteOptionalTypeParameters(node, ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
 		}
 		try {
 			pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
@@ -1858,7 +1950,7 @@
 				int endPos= getScanner().getTokenStartOffset(ITerminalSymbols.TokenNamewhile, bodyEnd);
 				rewriteBodyNode(node, DoStatement.BODY_PROPERTY, startOffset, endPos, getIndent(node.getStartPosition()), this.formatter.DO_BLOCK); // body
 			} else {
-				doVisit(node, DoStatement.BODY_PROPERTY, pos);
+				voidVisit(node, DoStatement.BODY_PROPERTY);
 			}
 		} catch (CoreException e) {
 			handleException(e);
@@ -1914,7 +2006,7 @@
 		}
 		int pos= rewriteJavadoc(node, FieldDeclaration.JAVADOC_PROPERTY);
 
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteModifiers(node, FieldDeclaration.MODIFIERS_PROPERTY, pos);
 		} else {
 			rewriteModifiers2(node, FieldDeclaration.MODIFIERS2_PROPERTY, pos);
@@ -1961,7 +2053,7 @@
 				int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos);
 				rewriteBodyNode(node, ForStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.FOR_BLOCK); // body
 			} else {
-				doVisit(node, ForStatement.BODY_PROPERTY, 0);
+				voidVisit(node, ForStatement.BODY_PROPERTY);
 			}
 			
 		} catch (CoreException e) {
@@ -2127,7 +2219,7 @@
 			return doVisitUnchangedChildren(node);
 		}
 		int pos= rewriteJavadoc(node, Initializer.JAVADOC_PROPERTY);
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteModifiers(node, Initializer.MODIFIERS_PROPERTY, pos);
 		} else {
 			rewriteModifiers2(node, Initializer.MODIFIERS2_PROPERTY, pos);
@@ -2186,7 +2278,7 @@
 		
 		int pos= rewriteOptionalQualifier(node, MethodInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
 		if (node.getAST().apiLevel() >= AST.JLS3) {
-			pos= rewriteOptionalTypeParameters(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, " "); //$NON-NLS-1$
+			pos= rewriteOptionalTypeParameters(node, MethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
 		}
 
 		pos= rewriteRequiredNode(node, MethodInvocation.NAME_PROPERTY);
@@ -2200,7 +2292,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, MethodInvocation.ARGUMENTS_PROPERTY, 0);
+			voidVisit(node, MethodInvocation.ARGUMENTS_PROPERTY);
 		}
 		return false;
 	}
@@ -2343,7 +2435,7 @@
 			return doVisitUnchangedChildren(node);
 		}
 		int pos= node.getStartPosition();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteModifiers(node, SingleVariableDeclaration.MODIFIERS_PROPERTY, pos);
 		} else {
 			rewriteModifiers2(node, SingleVariableDeclaration.MODIFIERS2_PROPERTY, pos);
@@ -2409,7 +2501,7 @@
 		int pos= rewriteOptionalQualifier(node, SuperConstructorInvocation.EXPRESSION_PROPERTY, node.getStartPosition());
 
 		if (node.getAST().apiLevel() >= AST.JLS3) {
-			pos= rewriteOptionalTypeParameters(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, " "); //$NON-NLS-1$
+			pos= rewriteOptionalTypeParameters(node, SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
 		}
 		
 		if (isChanged(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY)) {
@@ -2421,7 +2513,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY, 0);
+			voidVisit(node, SuperConstructorInvocation.ARGUMENTS_PROPERTY);
 		}
 		return false;		
 	}
@@ -2453,7 +2545,7 @@
 			if (isChanged(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY)) {
 				try {
 					pos= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameDOT, pos);
-					rewriteOptionalTypeParameters(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, " "); //$NON-NLS-1$
+					rewriteOptionalTypeParameters(node, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY, pos, "", false); //$NON-NLS-1$
 				} catch (CoreException e) {
 					handleException(e);
 				}
@@ -2471,7 +2563,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, SuperMethodInvocation.ARGUMENTS_PROPERTY, 0);
+			voidVisit(node, SuperMethodInvocation.ARGUMENTS_PROPERTY);
 		}		
 		return false;	
 	}
@@ -2533,7 +2625,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, SwitchStatement.STATEMENTS_PROPERTY, 0);
+			voidVisit(node, SwitchStatement.STATEMENTS_PROPERTY);
 		}
 		return false;		
 	}
@@ -2587,7 +2679,7 @@
 		
 		if (isChanged(node, TryStatement.CATCH_CLAUSES_PROPERTY)) {
 			int indent= getIndent(node.getStartPosition());
-			String prefix= this.formatter.CATCH_BLOCK.getPrefix(indent, getLineDelimiter());
+			String prefix= this.formatter.CATCH_BLOCK.getPrefix(indent);
 			pos= rewriteNodeList(node, TryStatement.CATCH_CLAUSES_PROPERTY, pos, prefix, prefix);
 		} else {
 			pos= doVisit(node, TryStatement.CATCH_CLAUSES_PROPERTY, pos);
@@ -2605,7 +2697,7 @@
 		if (!hasChildrenChanges(node)) {
 			return doVisitUnchangedChildren(node);
 		}
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteRequiredNode(node, TypeDeclarationStatement.TYPE_DECLARATION_PROPERTY);	
 		} else {
 			rewriteRequiredNode(node, TypeDeclarationStatement.DECLARATION_PROPERTY);	
@@ -2635,7 +2727,7 @@
 		
 		// same code as FieldDeclaration
 		int pos= node.getStartPosition();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteModifiers(node, VariableDeclarationExpression.MODIFIERS_PROPERTY, pos);
 		} else {
 			rewriteModifiers2(node, VariableDeclarationExpression.MODIFIERS2_PROPERTY, pos);
@@ -2683,7 +2775,7 @@
 		
 		// same code as FieldDeclaration
 		int pos= node.getStartPosition();
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			rewriteModifiers(node, VariableDeclarationStatement.MODIFIERS_PROPERTY, pos);
 		} else {
 			rewriteModifiers2(node, VariableDeclarationStatement.MODIFIERS2_PROPERTY, pos);
@@ -2709,7 +2801,7 @@
 				int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameRPAREN, pos);
 				rewriteBodyNode(node, WhileStatement.BODY_PROPERTY, startOffset, -1, getIndent(node.getStartPosition()), this.formatter.WHILE_BLOCK); // body
 			} else {
-				doVisit(node, WhileStatement.BODY_PROPERTY, 0);
+				voidVisit(node, WhileStatement.BODY_PROPERTY);
 			}
 		} catch (CoreException e) {
 			handleException(e);
@@ -2750,7 +2842,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, MethodRef.PARAMETERS_PROPERTY, 0);
+			voidVisit(node, MethodRef.PARAMETERS_PROPERTY);
 		}
 		return false;
 	}
@@ -2763,6 +2855,20 @@
 			return doVisitUnchangedChildren(node);
 		}
 		int pos= rewriteRequiredNode(node, MethodRefParameter.TYPE_PROPERTY);
+		if (node.getAST().apiLevel() >= AST.JLS3) {
+			if (isChanged(node, MethodRefParameter.VARARGS_PROPERTY)) {
+				if (getNewValue(node, MethodRefParameter.VARARGS_PROPERTY).equals(Boolean.TRUE)) {
+					doTextInsert(pos, "...", getEditGroup(node, MethodRefParameter.VARARGS_PROPERTY)); //$NON-NLS-1$
+				} else {
+					try {
+						int ellipsisEnd= getScanner().getNextEndOffset(pos, true);
+						doTextRemove(pos, ellipsisEnd - pos, getEditGroup(node, MethodRefParameter.VARARGS_PROPERTY)); //$NON-NLS-1$
+					} catch (CoreException e) {
+						handleException(e);
+					}
+				}
+			}
+		}
 		rewriteNode(node, MethodRefParameter.NAME_PROPERTY, pos, ASTRewriteFormatter.SPACE); //$NON-NLS-1$
 		return false;
 	}
@@ -2807,7 +2913,7 @@
             
             rewriteNodeList(node, TagElement.FRAGMENTS_PROPERTY, startOffset, " ", " ");  //$NON-NLS-1$//$NON-NLS-2$
 		} else {
-			doVisit(node, TagElement.FRAGMENTS_PROPERTY, 0);
+			voidVisit(node, TagElement.FRAGMENTS_PROPERTY);
 		}
 		return false;
 	}
@@ -2903,7 +3009,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, EnhancedForStatement.BODY_PROPERTY, 0);
+			voidVisit(node, EnhancedForStatement.BODY_PROPERTY);
 		}
 		return false;
 	}
@@ -2973,18 +3079,40 @@
 		int pos= rewriteJavadoc(node, EnumDeclaration.JAVADOC_PROPERTY);
 		rewriteModifiers2(node, EnumDeclaration.MODIFIERS2_PROPERTY, pos);
 		pos= rewriteRequiredNode(node, EnumDeclaration.NAME_PROPERTY);
-		rewriteNodeList(node, EnumDeclaration.SUPER_INTERFACE_TYPES_PROPERTY, pos, " implements ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
+		pos= rewriteNodeList(node, EnumDeclaration.SUPER_INTERFACE_TYPES_PROPERTY, pos, " implements ", ", "); //$NON-NLS-1$ //$NON-NLS-2$
+
+		pos= getPosAfterLeftBrace(pos);
 		
-		pos= rewriteNodeList(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY, pos, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
+		String leadString= ""; //$NON-NLS-1$
+		RewriteEvent constEvent= getEvent(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
+
+		if (constEvent != null && constEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
+			RewriteEvent[] events= constEvent.getChildren();
+			if (isAllOfKind(events, RewriteEvent.INSERTED)) {
+				leadString= this.formatter.FIRST_ENUM_CONST.getPrefix(getIndent(node.getStartPosition()));
+			}
+		}
+		pos= rewriteNodeList(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY, pos, leadString, ", "); //$NON-NLS-1$ //$NON-NLS-2$
 
 		RewriteEvent bodyEvent= getEvent(node, EnumDeclaration.BODY_DECLARATIONS_PROPERTY);
 		int indent= 0;
 		if (bodyEvent != null && bodyEvent.getChangeKind() != RewriteEvent.UNCHANGED) {
+			boolean hasConstants= !((List) getNewValue(node, EnumDeclaration.ENUM_CONSTANTS_PROPERTY)).isEmpty();
+			
 			RewriteEvent[] children= bodyEvent.getChildren();
 			try {
+				if (hasConstants) {
+					indent= getIndent(pos);
+				} else {
+					indent= getIndent(node.getStartPosition()) + 1;
+				}
 				int token= getScanner().readNext(pos, true);
 				boolean hasSemicolon= token == ITerminalSymbols.TokenNameSEMICOLON;
 				if (!hasSemicolon && isAllOfKind(children, RewriteEvent.INSERTED)) {
+					if (!hasConstants) {
+						String str= this.formatter.FIRST_ENUM_CONST.getPrefix(indent - 1);
+						doTextInsert(pos, str, getEditGroup(children[0])); //$NON-NLS-1$
+					}
 					doTextInsert(pos, ";", getEditGroup(children[0])); //$NON-NLS-1$
 				} else if (hasSemicolon) {
 					int endPos= getScanner().getCurrentEndOffset();
@@ -2993,7 +3121,6 @@
 					}
 					pos= endPos;
 				}
-				indent= getIndent(pos);
 			} catch (CoreException e) {
 				handleException(e);
 			}
@@ -3046,13 +3173,13 @@
 		if (isChanged(node, NormalAnnotation.VALUES_PROPERTY)) {
 			// eval position after opening parent
 			try {
-				int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLESS, pos);
+				int startOffset= getScanner().getTokenEndOffset(ITerminalSymbols.TokenNameLPAREN, pos);
 				rewriteNodeList(node, NormalAnnotation.VALUES_PROPERTY, startOffset, "", ", "); //$NON-NLS-1$ //$NON-NLS-2$
 			} catch (CoreException e) {
 				handleException(e);
 			}
 		} else {
-			doVisit(node, NormalAnnotation.VALUES_PROPERTY, 0);
+			voidVisit(node, NormalAnnotation.VALUES_PROPERTY);
 		}
 		return false;
 	}
@@ -3073,7 +3200,7 @@
 				handleException(e);
 			}
 		} else {
-			doVisit(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY, 0);
+			voidVisit(node, ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
 		}
 		return false;
 	}
@@ -3110,7 +3237,7 @@
 		if (isChanged(node, TypeParameter.TYPE_BOUNDS_PROPERTY)) {
 			rewriteNodeList(node, TypeParameter.TYPE_BOUNDS_PROPERTY, pos, " extends ", " & "); //$NON-NLS-1$ //$NON-NLS-2$
 		} else {
-			doVisit(node, TypeParameter.TYPE_BOUNDS_PROPERTY, 0);
+			voidVisit(node, TypeParameter.TYPE_BOUNDS_PROPERTY);
 		}
 		return false;
 	}
@@ -3136,7 +3263,7 @@
 				int boundTypeChange= getChangeKind(node, WildcardType.BOUND_PROPERTY);
 				if (boundTypeChange != RewriteEvent.INSERTED && boundTypeChange != RewriteEvent.REMOVED) {
 					ASTNode type= (ASTNode) getOriginalValue(node, WildcardType.BOUND_PROPERTY);
-					String str= prefix.getPrefix(0, getLineDelimiter());
+					String str= prefix.getPrefix(0);
 					doTextReplace(pos, type.getStartPosition() - pos, str, getEditGroup(node, WildcardType.BOUND_PROPERTY));
 				}
 			}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
index 69bc159..a8a9b20 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,6 +16,13 @@
 
 public class ASTRewriteFlattener extends ASTVisitor {
 	
+	/**
+	 * Internal synonynm for deprecated constant AST.JSL2
+	 * to alleviate deprecation warnings.
+	 * @deprecated
+	 */
+	/*package*/ static final int JLS2_INTERNAL = AST.JLS2;
+	
 	public static String asString(ASTNode node, RewriteEventStore store) {
 		ASTRewriteFlattener flattener= new ASTRewriteFlattener(store);
 		node.accept(flattener);
@@ -315,7 +322,7 @@
 			this.result.append('.');
 		}
 		this.result.append("new ");//$NON-NLS-1$
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			getChildNode(node, ClassInstanceCreation.NAME_PROPERTY).accept(this);
 		} else {
 			visitList(node, ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
@@ -431,7 +438,7 @@
 		if (javadoc != null) {
 			javadoc.accept(this);
 		}
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, FieldDeclaration.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, FieldDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -535,7 +542,7 @@
 		if (javadoc != null) {
 			javadoc.accept(this);
 		}
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, Initializer.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, Initializer.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -576,7 +583,7 @@
 		if (javadoc != null) {
 			javadoc.accept(this);
 		}
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, MethodDeclaration.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, MethodDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -584,7 +591,7 @@
 		}
 				
 		if (!getBooleanAttribute(node, MethodDeclaration.CONSTRUCTOR_PROPERTY)) {
-			if (node.getAST().apiLevel() == AST.JLS2) {
+			if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 				getChildNode(node, MethodDeclaration.RETURN_TYPE_PROPERTY).accept(this);
 			} else {
 				ASTNode returnType = getChildNode(node, MethodDeclaration.RETURN_TYPE2_PROPERTY);
@@ -747,7 +754,7 @@
 	 * @see ASTVisitor#visit(SingleVariableDeclaration)
 	 */
 	public boolean visit(SingleVariableDeclaration node) {
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, SingleVariableDeclaration.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, SingleVariableDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -921,7 +928,7 @@
 			javadoc.accept(this);
 		}
 
-		if (apiLevel == AST.JLS2) {
+		if (apiLevel == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, TypeDeclaration.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, TypeDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -936,7 +943,7 @@
 
 		this.result.append(' ');
 		
-		ChildPropertyDescriptor superClassProperty= (apiLevel == AST.JLS2) ? TypeDeclaration.SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY;
+		ChildPropertyDescriptor superClassProperty= (apiLevel == JLS2_INTERNAL) ? TypeDeclaration.SUPERCLASS_PROPERTY : TypeDeclaration.SUPERCLASS_TYPE_PROPERTY;
 		ASTNode superclass= getChildNode(node, superClassProperty);
 		if (superclass != null) {
 			this.result.append("extends "); //$NON-NLS-1$
@@ -944,7 +951,7 @@
 			this.result.append(' ');
 		}
 		
-		ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == AST.JLS2) ? TypeDeclaration.SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY;
+		ChildListPropertyDescriptor superInterfaceProperty= (apiLevel == JLS2_INTERNAL) ? TypeDeclaration.SUPER_INTERFACES_PROPERTY : TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY;
 		String lead= isInterface ? "extends " : "implements ";  //$NON-NLS-1$//$NON-NLS-2$
 		visitList(node, superInterfaceProperty, String.valueOf(','), lead, EMPTY);
 		this.result.append('{');
@@ -957,7 +964,7 @@
 	 * @see ASTVisitor#visit(TypeDeclarationStatement)
 	 */
 	public boolean visit(TypeDeclarationStatement node) {
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			getChildNode(node, TypeDeclarationStatement.TYPE_DECLARATION_PROPERTY).accept(this);
 		} else {
 			getChildNode(node, TypeDeclarationStatement.DECLARATION_PROPERTY).accept(this);
@@ -978,7 +985,7 @@
 	 * @see ASTVisitor#visit(VariableDeclarationExpression)
 	 */
 	public boolean visit(VariableDeclarationExpression node) {
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, VariableDeclarationExpression.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, VariableDeclarationExpression.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -1010,7 +1017,7 @@
 	 * @see ASTVisitor#visit(VariableDeclarationStatement)
 	 */
 	public boolean visit(VariableDeclarationStatement node) {
-		if (node.getAST().apiLevel() == AST.JLS2) {
+		if (node.getAST().apiLevel() == JLS2_INTERNAL) {
 			printModifiers(getIntAttribute(node, VariableDeclarationStatement.MODIFIERS_PROPERTY), this.result);
 		} else {
 			visitList(node, VariableDeclarationStatement.MODIFIERS2_PROPERTY, String.valueOf(' '), EMPTY, String.valueOf(' '));
@@ -1078,6 +1085,11 @@
 	 */
 	public boolean visit(MethodRefParameter node) {
 		getChildNode(node, MethodRefParameter.TYPE_PROPERTY).accept(this);
+		if (node.getAST().apiLevel() >= AST.JLS3) {
+			if (getBooleanAttribute(node, MethodRefParameter.VARARGS_PROPERTY)) {
+				this.result.append("..."); //$NON-NLS-1$
+			}
+		}
 		ASTNode name= getChildNode(node, MethodRefParameter.NAME_PROPERTY);
 		if (name != null) {
 			this.result.append(' ');
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
index 574ccc3..c0a105f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -38,7 +38,7 @@
 import org.eclipse.jdt.core.dom.Expression;
 import org.eclipse.jdt.core.dom.Statement;
 
-/* package */ class ASTRewriteFormatter {
+/* package */ final class ASTRewriteFormatter {
 
 	public static class NodeMarker extends Position {
 		public Object data;
@@ -118,12 +118,13 @@
 	
 	final String lineDelimiter;
 	final int tabWidth;
-	final String singleIndentString;
+	final int indentWidth;
 	
 	final NodeInfoStore placeholders;
 	final RewriteEventStore eventStore;
 
 	final Map options;
+
 	
 	public ASTRewriteFormatter(NodeInfoStore placeholders, RewriteEventStore eventStore, Map options, String lineDelimiter) {
 		this.placeholders= placeholders;
@@ -137,29 +138,11 @@
 		this.options= options;
 		this.lineDelimiter= lineDelimiter;
 		
-		int tabWidthVal;
-		try {
-			tabWidthVal= Integer.parseInt((String) options.get(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE));
-		} catch (NumberFormatException e) {
-			tabWidthVal= 4;
-		}
-		this.tabWidth= tabWidthVal;
-		
-		String indent;
-		String code= "x"; //$NON-NLS-1$
-    	TextEdit edit= formatString(CodeFormatter.K_EXPRESSION, code, 1, "", options); //$NON-NLS-1$
-    	if (edit != null) {
-    		String str= evaluateFormatterEdit(code, edit, null);
-    		indent= str.substring(0, str.indexOf(code));
-    	} else {
-    	   indent= String.valueOf('\t');
-    	}
-		this.singleIndentString= indent;
+		this.tabWidth= Indents.getTabWidth(options);
+		this.indentWidth= Indents.getIndentWidth(options, this.tabWidth);
 	}
 	
-	public int getTabWidth() {
-		return this.tabWidth;
-	}
+
 	
 	public NodeInfoStore getPlaceholders() {
 		return this.placeholders;
@@ -198,7 +181,7 @@
 		    if (initialIndentationLevel > 0) {
 		        // at least correct the indent
 		        String indentString = createIndentString(initialIndentationLevel);
-				ReplaceEdit[] edits = Indents.getChangeIndentEdits(unformatted, 0, this.tabWidth, indentString);
+				ReplaceEdit[] edits = Indents.getChangeIndentEdits(unformatted, 0, this.tabWidth, this.indentWidth, indentString);
 				edit= new MultiTextEdit();
 				edit.addChild(new InsertEdit(0, indentString));
 				edit.addChildren(edits);
@@ -211,17 +194,56 @@
 	
     /**
      * Creates a string that represents the given number of indents (can be spaces or tabs..)
-     * @param indent
+     * @param indentationUnits the indent to represent
      * @return Returns the created indent
      */
-    public String createIndentString(int indent) {
-        StringBuffer buf= new StringBuffer(indent * this.singleIndentString.length());
-        for (int i = 0; i < indent; i++) {
-            buf.append(this.singleIndentString);
-        }
-        return buf.toString();
+    public String createIndentString(int indentationUnits) {
+		final String tabChar= (String) options.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
+		final int tabs, spaces;
+		if (JavaCore.SPACE.equals(tabChar)) {
+			tabs= 0;
+			spaces= indentationUnits * this.indentWidth;
+		} else if (JavaCore.TAB.equals(tabChar)) {
+			// indentWidth == tabWidth
+			tabs= indentationUnits;
+			spaces= 0;
+		} else if (DefaultCodeFormatterConstants.MIXED.equals(tabChar)){
+			int spaceEquivalents= indentationUnits * this.indentWidth;
+			if (this.tabWidth > 0) {
+				tabs= spaceEquivalents / this.tabWidth;
+				spaces= spaceEquivalents % this.tabWidth;
+			} else {
+				tabs= 0;
+				spaces= spaceEquivalents;
+			}
+		} else {
+			// new indent type not yet handled
+			//Assert.isTrue(false); bug 90580
+			tabs= 0;
+			spaces= indentationUnits * this.indentWidth;
+		}
+		
+		StringBuffer buffer= new StringBuffer(tabs + spaces);
+		for(int i= 0; i < tabs; i++)
+			buffer.append('\t');
+		for(int i= 0; i < spaces; i++)
+			buffer.append(' ');
+		return buffer.toString();
+
     }
 	
+	public String getIndentString(String currentLine) {
+		return Indents.getIndentString(currentLine, this.tabWidth, this.indentWidth);
+	}
+	
+	public String changeIndent(String code, int codeIndentLevel, String newIndent) {
+		return Indents.changeIndent(code, codeIndentLevel, this.tabWidth, this.indentWidth, newIndent, this.lineDelimiter);
+	}
+	
+	public int computeIndentUnits(String line) {
+		return Indents.computeIndentUnits(line, this.tabWidth, this.indentWidth);
+	}
+	
 	/**
 	 * Evaluates the edit on the given string.
 	 * @param string The string to format
@@ -420,11 +442,11 @@
     
 
     public static interface Prefix {
-		String getPrefix(int indent, String lineDelim);
+		String getPrefix(int indent);
 	}
 	
 	public static interface BlockContext {
-		String[] getPrefixAndSuffix(int indent, String lineDelim, ASTNode node, RewriteEventStore events);
+		String[] getPrefixAndSuffix(int indent, ASTNode node, RewriteEventStore events);
 	}	
 	
 	public static class ConstPrefix implements Prefix {
@@ -434,7 +456,7 @@
 			this.prefix= prefix;
 		}
 		
-		public String getPrefix(int indent, String lineDelim) {
+		public String getPrefix(int indent) {
 			return this.prefix;
 		}
 	}
@@ -452,10 +474,10 @@
 			this.kind= kind;
 		}
 		
-		public String getPrefix(int indent, String lineDelim) {
+		public String getPrefix(int indent) {
 			Position pos= new Position(this.start, this.length);
 			String str= this.string;
-			TextEdit res= formatString(this.kind, str, indent, lineDelim, getOptions());
+			TextEdit res= formatString(this.kind, str, indent, lineDelimiter, getOptions());
 			if (res != null) {
 				str= evaluateFormatterEdit(str, res, new Position[] { pos });
 			}
@@ -472,12 +494,12 @@
 			this.prefix= prefix;
 		}
 		
-		public String[] getPrefixAndSuffix(int indent, String lineDelim, ASTNode node, RewriteEventStore events) {
+		public String[] getPrefixAndSuffix(int indent, ASTNode node, RewriteEventStore events) {
 			String nodeString= ASTRewriteFlattener.asString(node, events);
 			String str= this.prefix + nodeString;
 			Position pos= new Position(this.start, this.prefix.length() + 1 - this.start);
 
-			TextEdit res= formatString(CodeFormatter.K_STATEMENTS, str, indent, lineDelim, getOptions());
+			TextEdit res= formatString(CodeFormatter.K_STATEMENTS, str, indent, lineDelimiter, getOptions());
 			if (res != null) {
 				str= evaluateFormatterEdit(str, res, new Position[] { pos });
 			}
@@ -496,7 +518,7 @@
 			this.prefix= prefix;
 		}
 		
-		public String[] getPrefixAndSuffix(int indent, String lineDelim, ASTNode node, RewriteEventStore events) {
+		public String[] getPrefixAndSuffix(int indent, ASTNode node, RewriteEventStore events) {
 			String nodeString= ASTRewriteFlattener.asString(node, events);
 			int nodeStart= this.prefix.length();
 			int nodeEnd= nodeStart + nodeString.length() - 1;
@@ -506,7 +528,7 @@
 			Position pos1= new Position(this.start, nodeStart + 1 - this.start);
 			Position pos2= new Position(nodeEnd, 2);
 
-			TextEdit res= formatString(CodeFormatter.K_STATEMENTS, str, indent, lineDelim, getOptions());
+			TextEdit res= formatString(CodeFormatter.K_STATEMENTS, str, indent, lineDelimiter, getOptions());
 			if (res != null) {
 				str= evaluateFormatterEdit(str, res, new Position[] { pos1, pos2 });
 			}
@@ -530,6 +552,8 @@
 	public final Prefix ENUM_BODY_END= new FormattingPrefix("enum E { A(){void foo(){ }}, B}", "}}," , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
 	public final Prefix WILDCARD_EXTENDS= new FormattingPrefix("A<? extends B> a;", "? extends B" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
 	public final Prefix WILDCARD_SUPER= new FormattingPrefix("A<? super B> a;", "? super B" , CodeFormatter.K_CLASS_BODY_DECLARATIONS); //$NON-NLS-1$ //$NON-NLS-2$
+
+	public final Prefix FIRST_ENUM_CONST= new FormattingPrefix("enum E { X;}", "{ X" , CodeFormatter.K_COMPILATION_UNIT); //$NON-NLS-1$ //$NON-NLS-2$
 	
 	public final BlockContext IF_BLOCK_WITH_ELSE= new BlockFormattingPrefixSuffix("if (true)", "else{}", 8); //$NON-NLS-1$ //$NON-NLS-2$
 	public final BlockContext IF_BLOCK_NO_ELSE= new BlockFormattingPrefix("if (true)", 8); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/Indents.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/Indents.java
index c5fbb72..05029cd 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/Indents.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/Indents.java
@@ -1,16 +1,18 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.dom.rewrite;
 
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
 
 import org.eclipse.jface.text.Assert;
 import org.eclipse.jface.text.BadLocationException;
@@ -18,6 +20,8 @@
 import org.eclipse.jface.text.ILineTracker;
 import org.eclipse.jface.text.IRegion;
 
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
 import org.eclipse.text.edits.ReplaceEdit;
 
 /**
@@ -47,99 +51,139 @@
 	public static boolean isLineDelimiterChar(char ch) { 
 		return ch == '\n' || ch == '\r';
 	}	
-
+	
 	/**
-	 * Returns the indent of the given string.
+	 * Returns the indent of the given string in indentation units. Odd spaces
+	 * are not counted.
 	 * 
 	 * @param line the text line
-	 * @param tabWidth the width of the '\t' character.
-	 * @return Returns the indent of the given string.
+	 * @param tabWidth the width of the '\t' character in space equivalents
+	 * @param indentWidth the width of one indentation unit in space equivalents
+	 * @since 3.1
 	 */
-	public static int computeIndent(String line, int tabWidth) {
-		int result= 0;
-		int blanks= 0;
-		int size= line.length();
-		for (int i= 0; i < size; i++) {
-			char c= line.charAt(i);
-			if (c == '\t') {
-				result++;
-				blanks= 0;
-			} else if (isIndentChar(c)) {
-				blanks++;
-				if (blanks == tabWidth) {
-					result++;
-					blanks= 0;
-				}
-			} else {
-				return result;
-			}
-		}
-		return result;
+	public static int computeIndentUnits(String line, int tabWidth, int indentWidth) {
+		if (indentWidth == 0)
+			return -1;
+		int visualLength= measureIndentLength(line, tabWidth);
+		return visualLength / indentWidth;
 	}
 	
 	/**
-	 * Removes the given number of idents from the line. Asserts that the given line 
+	 * Computes the visual length of the indentation of a
+	 * <code>CharSequence</code>, counting a tab character as the size until
+	 * the next tab stop and every other whitespace character as one.
+	 * 
+	 * @param line the string to measure the indent of
+	 * @param tabSize the visual size of a tab in space equivalents
+	 * @return the visual length of the indentation of <code>line</code>
+	 * @since 3.1
+	 */
+	public static int measureIndentLength(CharSequence line, int tabSize) {
+		int length= 0;
+		int max= line.length();
+		for (int i= 0; i < max; i++) {
+			char ch= line.charAt(i);
+			if (ch == '\t') {
+				int reminder= length % tabSize;
+				length += tabSize - reminder;
+			} else if (isIndentChar(ch)) {
+				length++;
+			} else {
+				return length;
+			}
+		}
+		return length;
+	}
+	
+	/**
+	 * Removes the given number of indents from the line. Asserts that the given line 
 	 * has the requested number of indents. If <code>indentsToRemove <= 0</code>
 	 * the line is returned.
-	 * @param line The line to trim the indent
-	 * @param indentsToRemove The indent level to remove
-	 * @param tabWidth The current tab width
-	 * @return Returns the trimed line
+	 * 
+	 * @since 3.1
 	 */
-	public static String trimIndent(String line, int indentsToRemove, int tabWidth) {
+	public static String trimIndent(String line, int indentsToRemove, int tabWidth, int indentWidth) {
 		if (line == null || indentsToRemove <= 0)
 			return line;
-			
+
+		final int spaceEquivalentsToRemove= indentsToRemove * indentWidth;
+		
 		int start= 0;
-		int indents= 0;
-		int blanks= 0;
+		int spaceEquivalents= 0;
 		int size= line.length();
+		String prefix= null;
 		for (int i= 0; i < size; i++) {
 			char c= line.charAt(i);
 			if (c == '\t') {
-				indents++;
-				blanks= 0;
+				int remainder= spaceEquivalents % tabWidth;
+				spaceEquivalents += tabWidth - remainder;
 			} else if (isIndentChar(c)) {
-					blanks++;
-					if (blanks == tabWidth) {
-						indents++;
-						blanks= 0;
-					}
+				spaceEquivalents++;
 			} else {
 				// Assert.isTrue(false, "Line does not have requested number of indents"); //$NON-NLS-1$
 				start= i;
 				break; 
 			}
-			if (indents == indentsToRemove) {
+			if (spaceEquivalents == spaceEquivalentsToRemove) {
 				start= i + 1;
 				break;
-			}	
+			}
+			if (spaceEquivalents > spaceEquivalentsToRemove) {
+				// can happen if tabSize > indentSize, e.g tabsize==8, indent==4, indentsToRemove==1, line prefixed with one tab
+				// this implements the third option
+				start= i + 1; // remove the tab
+				// and add the missing spaces
+				char[] missing= new char[spaceEquivalents - spaceEquivalentsToRemove];
+				Arrays.fill(missing, ' ');
+				prefix= new String(missing);
+				break;
+			}
 		}
+		String trimmed;
 		if (start == size)
-			return ""; //$NON-NLS-1$
+			trimmed= ""; //$NON-NLS-1$
 		else
-			return line.substring(start);
+			trimmed= line.substring(start);
+		
+		if (prefix == null)
+			return trimmed;
+		return prefix + trimmed;
 	}
 
+
 	
-	public static String getIndentString(String line, int tabWidth) {
+	/**
+	 * Returns that part of the indentation of <code>line</code> that makes up
+	 * a multiple of indentation units.
+	 * 
+	 * @param line the line to scan
+	 * @param tabWidth the size of one tab in space equivalents
+	 * @return the indent part of <code>line</code>, but no odd spaces
+	 * @since 3.1
+	 */
+	public static String getIndentString(String line, int tabWidth, int indentWidth) {
 		int size= line.length();
 		int end= 0;
-		int blanks= 0;
+		
+		int spaceEquivs= 0;
+		int characters= 0;
 		for (int i= 0; i < size; i++) {
 			char c= line.charAt(i);
 			if (c == '\t') {
-				end= i + 1;
-				blanks= 0;
+				int remainder= spaceEquivs % tabWidth;
+				spaceEquivs += tabWidth - remainder;
+				characters++;
 			} else if (isIndentChar(c)) {
-				blanks++;
-				if (blanks == tabWidth) {
-					end= i + 1;
-					blanks= 0;
-				}
+				spaceEquivs++;
+				characters++;
 			} else {
 				break;
 			}
+			if (spaceEquivs >= indentWidth) {
+				end += characters;
+				characters= 0;
+				spaceEquivs= spaceEquivs % indentWidth;
+			}
 		}
 		if (end == 0)
 			return ""; //$NON-NLS-1$
@@ -153,38 +197,32 @@
 	 * Returns the length of the string representing the number of 
 	 * indents in the given string <code>line</code>. Returns 
 	 * <code>-1<code> if the line isn't prefixed with an indent of
-	 * the given number of indents. 
-	 * @param line
-	 * @param numberOfIndents
-	 * @param tabWidth
-	 * @return Returns the length of the string representing the number of 
-	 * indents
+	 * the given number of indents.
+	 * @since 3.1
 	 */
-	public static int computeIndentLength(String line, int numberOfIndents, int tabWidth) {
+	public static int computeIndentLength(String line, int numberOfIndents, int tabWidth, int indentWidth) {
 		Assert.isTrue(numberOfIndents >= 0);
 		Assert.isTrue(tabWidth >= 0);
+		Assert.isTrue(indentWidth >= 0);
+		
+		int spaceEquivalents= numberOfIndents * indentWidth;
+		
 		int size= line.length();
 		int result= -1;
-		int indents= 0;
 		int blanks= 0;
-		for (int i= 0; i < size && indents < numberOfIndents; i++) {
+		for (int i= 0; i < size && blanks < spaceEquivalents; i++) {
 			char c= line.charAt(i);
 			if (c == '\t') {
-				indents++;
-				result= i;
-				blanks= 0;
+				int remainder= blanks % tabWidth;
+				blanks += tabWidth - remainder;
 			} else if (isIndentChar(c)) {
 				blanks++;
-				if (blanks == tabWidth) {
-					result= i;
-					indents++;
-					blanks= 0;
-				}
 			} else {
 				break;
 			}
+			result= i;
 		}
-		if (indents < numberOfIndents)
+		if (blanks < spaceEquivalents)
 			return -1;
 		return result + 1;
 	}
@@ -193,14 +231,9 @@
 	 * Change the indent of, possible muti-line, code range. The current indent is removed, a new indent added.
 	 * The first line of the code will not be changed. (It is considered to have no indent as it might start in
 	 * the middle of a line)
-	 * @param code The code to change the indent of
-	 * @param codeIndentLevel The indent level of the code
-	 * @param tabWidth The current tab width setting
-	 * @param newIndent The new Indent string
-	 * @param lineDelim THe current line delimiter
-	 * @return Returns the newly indented code
+	 * @since 3.1
 	 */
-	public static String changeIndent(String code, int codeIndentLevel, int tabWidth, String newIndent, String lineDelim) {
+	public static String changeIndent(String code, int codeIndentLevel, int tabWidth, int indentWidth, String newIndent, String lineDelim) {
 		try {
 			ILineTracker tracker= new DefaultLineTracker();
 			tracker.set(code);
@@ -222,7 +255,7 @@
 				} else { // no new line after last line
 					buf.append(lineDelim);
 					buf.append(newIndent); 
-					buf.append(trimIndent(line, codeIndentLevel, tabWidth));
+					buf.append(trimIndent(line, codeIndentLevel, tabWidth, indentWidth));
 				}
 			}
 			return buf.toString();
@@ -231,7 +264,7 @@
 			return code;
 		}
 	}
-	
+
 	/**
 	 * Change the indent of, possible muti-line, code range. The current indent is removed, a new indent added.
 	 * The first line of the code will not be changed. (It is considered to have no indent as it might start in
@@ -242,7 +275,7 @@
 	 * @param newIndent The new Indent string
 	 * @return Returns the resulting text edits
 	 */
-	public static ReplaceEdit[] getChangeIndentEdits(String source, int sourceIndentLevel, int tabWidth, String newIndent) {
+	public static ReplaceEdit[] getChangeIndentEdits(String source, int sourceIndentLevel, int tabWidth, int indentWidth, String newIndent) {
 	    ArrayList result= new ArrayList();
 		try {
 			ILineTracker tracker= new DefaultLineTracker();
@@ -254,11 +287,11 @@
 				IRegion region= tracker.getLineInformation(i);
 				int offset= region.getOffset();
 				String line= source.substring(offset, offset + region.getLength());
-				int length= Indents.computeIndentLength(line, sourceIndentLevel, tabWidth);
+				int length= Indents.computeIndentLength(line, sourceIndentLevel, tabWidth, indentWidth);
 				if (length >= 0) {
 					result.add(new ReplaceEdit(offset, length, newIndent));
 				} else {
-					length= Indents.computeIndent(line, tabWidth);
+					length= Indents.computeIndentUnits(line, tabWidth, indentWidth);
 					result.add(new ReplaceEdit(offset, length, "")); //$NON-NLS-1$
 				}
 			}
@@ -267,6 +300,59 @@
 		}
 		return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]);
 	}
+	
+	/**
+	 * Returns the tab width as configured in the given map.
+	 * @param options The options to look at
+	 * @return the tab width
+	 */
+	public static int getTabWidth(Map options) {
+		return parseIntValue(options, DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, 4);
+	}
+	
+	/**
+	 * Returns the tab width as configured in the given map.
+	 * @param options The options to look at
+	 * 	@param tabWidth the tab width
+	 * @return the indent width
+	 */
+	public static int getIndentWidth(Map options, int tabWidth) {
+		boolean isMixedMode= DefaultCodeFormatterConstants.MIXED.equals(options.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
+		if (isMixedMode) {
+			return parseIntValue(options, DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, tabWidth);
+		}
+		return tabWidth;
+	}
+	
+	private static int parseIntValue(Map options, String key, int def) {
+		try {
+			return Integer.parseInt((String) options.get(key));
+		} catch (NumberFormatException e) {
+			return def;
+		}
+	}
+	
+
+	/**
+	 * Change the indent of, possible muti-line, code range. The current indent is removed, a new indent added.
+	 * The first line of the code will not be changed. (It is considered to have no indent as it might start in
+	 * the middle of a line)
+	 * @deprecated use the version specifying the indent width instead
+	 */
+	public static String changeIndent(String code, int codeIndentLevel, int tabWidth, String newIndent, String lineDelim) {
+		return changeIndent(code, codeIndentLevel, tabWidth, tabWidth, newIndent, lineDelim);
+	}
+
+	/**
+	 * Returns the indent of the given string.
+	 * 
+	 * @param line the text line
+	 * @param tabWidth the width of the '\t' character.
+	 * @deprecated use {@link #computeIndentUnits(String, int, int)} instead
+	 */
+	public static int computeIndent(String line, int tabWidth) {
+		return computeIndentUnits(line, tabWidth, tabWidth);
+	}
 
 }
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java
index bd269e5..9ffed08 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ListRewriteEvent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java
index 668994a..badb11e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeInfoStore.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,6 +20,7 @@
 import org.eclipse.jdt.core.dom.Block;
 import org.eclipse.jdt.core.dom.FieldDeclaration;
 import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.ParameterizedType;
 import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
@@ -89,6 +90,9 @@
 				case ASTNode.VARIABLE_DECLARATION_STATEMENT :
 				    ((VariableDeclarationStatement) node).fragments().add(this.ast.newVariableDeclarationFragment());
 		    		break;
+				case ASTNode.PARAMETERIZED_TYPE :
+				    ((ParameterizedType) node).typeArguments().add(this.ast.newWildcardType()); //$NON-NLS-1$
+		    		break;
 			}
 		    return node;
 	    } catch (IllegalArgumentException e) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java
index ddb0fcc..d4133f7 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/NodeRewriteEvent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java
index a2b0f45..36bc228 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEvent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
index c9512e7..1445334 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/RewriteEventStore.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -554,7 +554,38 @@
 	
 	
 	private void assertNoOverlap(CopySourceInfo copySource) {
-		// todo
+		ASTNode parent= copySource.parent;
+		StructuralPropertyDescriptor childProperty= copySource.childProperty;
+		ASTNode first= copySource.getStartNode();
+		ASTNode last= copySource.getEndNode();
+		
+		ListRewriteEvent listEvent= getListEvent(parent, childProperty, true);
+		
+		int indexFirst= listEvent.getIndex(first, ListRewriteEvent.OLD);
+		if (indexFirst == -1) {
+			throw new IllegalArgumentException("Start node is not a original child of the given list"); //$NON-NLS-1$
+		}
+		int indexLast= listEvent.getIndex(last, ListRewriteEvent.OLD);
+		if (indexLast == -1) {
+			throw new IllegalArgumentException("End node is not a original child of the given list"); //$NON-NLS-1$
+		}
+
+		if (indexFirst > indexLast) {
+			throw new IllegalArgumentException("Start node must be before end node"); //$NON-NLS-1$
+		}
+		if (this.rangeCopySources != null) {
+			for (Iterator iter= this.rangeCopySources.iterator(); iter.hasNext();) {
+				CopySourceInfo info= (CopySourceInfo) iter.next();
+				if (info.parent == parent && info.childProperty == childProperty) {
+					int currStart= listEvent.getIndex(first, ListRewriteEvent.BOTH);
+					int currEnd= listEvent.getIndex(first, ListRewriteEvent.BOTH);
+					if (currStart < indexFirst && currEnd < indexLast && currEnd >= indexFirst
+							|| currStart > indexFirst && currStart <= currEnd && currEnd > indexLast) {
+						throw new IllegalArgumentException("Range overlapps with an existing copy or move range"); //$NON-NLS-1$ 
+					}
+				}
+			}
+		}
 	}
 	
 	/**
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java
index 1ddb95d..ba4b001 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/SourceModifier.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -22,11 +22,13 @@
 	private final String destinationIndent;
 	private final int sourceIndentLevel;
 	private final int tabWidth;
+	private final int indentWidth;
 		
-	public SourceModifier(int sourceIndentLevel, String destinationIndent, int tabWidth) {
+	public SourceModifier(int sourceIndentLevel, String destinationIndent, int tabWidth, int indentWidth) {
 		this.destinationIndent= destinationIndent;
 		this.sourceIndentLevel= sourceIndentLevel;
 		this.tabWidth= tabWidth;
+		this.indentWidth= indentWidth;
 	}
 		
 	public ISourceModifier copy() {
@@ -36,10 +38,10 @@
 	
 	public ReplaceEdit[] getModifications(String source) {
 		List result= new ArrayList();
-		int destIndentLevel= Indents.computeIndent(this.destinationIndent, this.tabWidth);
+		int destIndentLevel= Indents.computeIndentUnits(this.destinationIndent, this.tabWidth, this.indentWidth);
 		if (destIndentLevel == this.sourceIndentLevel) {
 			return (ReplaceEdit[])result.toArray(new ReplaceEdit[result.size()]);
 		}
-		return Indents.getChangeIndentEdits(source, this.sourceIndentLevel, this.tabWidth, this.destinationIndent);
+		return Indents.getChangeIndentEdits(source, this.sourceIndentLevel, this.tabWidth, this.indentWidth, this.destinationIndent);
 	}
 }
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java
index 919eda6..98771aa 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TokenScanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
index 303ffbb..253b478 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/TrackedNodePosition.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -48,4 +48,4 @@
 		}
 		return TextEdit.getCoverage(this.group.getTextEdits()).getLength();
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java
index 4123b8d..8352e9b 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetAllocationExpression.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -199,7 +199,7 @@
 		    TypeBinding argumentType = argumentTypes[i];
 			arguments[i].computeConversion(scope, parameterType, argumentType);
 			if (argumentType.needsUncheckedConversion(parameterType)) {
-				scope.problemReporter().unsafeRawConversion(arguments[i], argumentType, parameterType);
+				scope.problemReporter().unsafeTypeConversion(arguments[i], argumentType, parameterType);
 			}
 		}
 		if (argsContainCast) {
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
index 0ddf602..501ecec 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -60,7 +60,7 @@
 	this.constantPool = new ConstantPool(this);
 	int accessFlags = aType.getAccessFlags();
 	
-	if (aType.isClass()) {
+	if (!aType.isInterface()) { // class or enum
 		accessFlags |= AccSuper;
 	}
 	if (aType.isNestedType()) {
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCodeStream.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCodeStream.java
index 123b89c..8457492 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCodeStream.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCodeStream.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java
index f4659ca..2896218 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetCompiler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java
index 19a8979..97872a8 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
index 7f1e743..d68a9ee 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetEvaluator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
index c6978b4..f93863a 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetFieldReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,6 +18,7 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
@@ -308,25 +309,24 @@
 	// if the binding declaring class is not visible, need special action
 	// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
 	// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
-	if (this.delegateThis != null) {
-		if (this.binding.declaringClass != this.delegateThis.type
-			&& this.binding.declaringClass != null
-			&& !this.binding.isConstantValue()
-			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2 
-					&& !this.binding.isStatic()
-					&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields (if there was any)
-				|| !this.codegenBinding.declaringClass.canBeSeenBy(currentScope))){
-			this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(this.codegenBinding, (ReferenceBinding)this.delegateThis.type.erasure());
+	TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.receiverType;
+	if (this.binding.declaringClass != someReceiverType
+			&& !someReceiverType.isArrayType()
+			&& this.binding.declaringClass != null // array.length
+			&& !this.binding.isConstantValue()) {
+	
+		CompilerOptions options = currentScope.environment().options;
+		if ((options.targetJDK >= ClassFileConstants.JDK1_2
+				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
+				&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields
+			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
+
+			this.codegenBinding =
+				currentScope.enclosingSourceType().getUpdatedFieldBinding(
+					this.codegenBinding,
+					(ReferenceBinding) someReceiverType.erasure());
 		}
-	} else if (this.binding.declaringClass != this.receiverType
-		&& !this.receiverType.isArrayType()
-		&& this.binding.declaringClass != null // array.length
-		&& !this.binding.isConstantValue()
-		&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
-				&& this.binding.declaringClass.id != T_JavaLangObject) //no change for Object fields (in case there was)
-			|| !this.codegenBinding.declaringClass.canBeSeenBy(currentScope))){
-			this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(this.codegenBinding, (ReferenceBinding) this.receiverType.erasure());
-	}
+	}	
 }
 public TypeBinding resolveType(BlockScope scope) {
 	// Answer the signature type of the field.
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
index 7d92c90..82214f8 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetMessageSend.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,6 +15,7 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
@@ -179,12 +180,18 @@
 	// NOTE: from target 1.2 on, method's declaring class is touched if any different from receiver type
 	// and not from Object or implicit static method call.	
 	if (this.binding.declaringClass != this.actualReceiverType
-		&& !this.actualReceiverType.isArrayType()
-		&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
-				&& (!this.receiver.isImplicitThis() || !this.codegenBinding.isStatic())
+			&& !this.actualReceiverType.isArrayType()) {
+		CompilerOptions options = currentScope.environment().options;
+		if ((options.targetJDK >= ClassFileConstants.JDK1_2
+				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !receiver.isImplicitThis() || !this.codegenBinding.isStatic())
 				&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object methods
-			|| !this.codegenBinding.declaringClass.canBeSeenBy(currentScope))) {
-		this.codegenBinding = currentScope.enclosingSourceType().getUpdatedMethodBinding(this.codegenBinding, (ReferenceBinding) this.actualReceiverType.erasure());
+			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
+
+			this.codegenBinding = currentScope.enclosingSourceType().getUpdatedMethodBinding(
+			        										this.codegenBinding, (ReferenceBinding) this.actualReceiverType.erasure());
+		}
+		// Post 1.4.0 target, array clone() invocations are qualified with array type 
+		// This is handled in array type #clone method binding resolution (see Scope and UpdatedMethodBinding)
 	}	
 }
 public TypeBinding resolveType(BlockScope scope) {
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
index d7f2a4a..19034b9 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -222,6 +222,24 @@
 	typeDecl.javadoc = this.javadoc;
 	this.javadoc = null;
 }
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.compilationUnit.types = new TypeDeclaration[length];
+		this.astPtr -= length;
+		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+	}
+}
 protected void consumeLocalVariableDeclarationStatement() {
 	super.consumeLocalVariableDeclarationStatement();
 	/* recovery */
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
index ebb9f18..caa1c50 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetQualifiedNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,6 +19,7 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -515,38 +516,44 @@
 		if (useDelegate) {
 			lastReceiverType = this.delegateThis.type;
 		}
+		// if the binding declaring class is not visible, need special action
+		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
+		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
+		// and not from Object or implicit static field access.	
 		if (fieldBinding.declaringClass != lastReceiverType
-			&& !lastReceiverType.isArrayType()			
-			&& fieldBinding.declaringClass != null
-			&& !fieldBinding.isConstantValue()
-			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
-					&& ((index < 0 ? fieldBinding != binding : index > 0) || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
-					&& fieldBinding.declaringClass.id != T_JavaLangObject)
+				&& !lastReceiverType.isArrayType()
+				&& fieldBinding.declaringClass != null // array.length
+				&& !fieldBinding.isConstantValue()) {
+			CompilerOptions options = currentScope.environment().options;
+			if ((options.targetJDK >= ClassFileConstants.JDK1_2
+					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || (index < 0 ? fieldBinding != binding : index > 0) || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
+					&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
 				|| !(useDelegate
 						? new CodeSnippetScope(currentScope).canBeSeenByForCodeSnippet(fieldBinding.declaringClass, (ReferenceBinding) this.delegateThis.type)
-						: fieldBinding.declaringClass.canBeSeenBy(currentScope)))){
-		    if (index < 0) { // write-access?
-				if (fieldBinding == this.binding){
+						: fieldBinding.declaringClass.canBeSeenBy(currentScope))) {
+	
+			    if (index < 0) { // write-access?
+					if (fieldBinding == this.binding){
+						this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
+					} else {
+						if (this.otherCodegenBindings == this.otherBindings){
+							int l = this.otherBindings.length;
+							System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l);
+						}
+						this.otherCodegenBindings[this.otherCodegenBindings.length-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
+					}
+			    } if (index == 0){
 					this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
 				} else {
 					if (this.otherCodegenBindings == this.otherBindings){
 						int l = this.otherBindings.length;
 						System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l);
 					}
-					this.otherCodegenBindings[this.otherCodegenBindings.length-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
+					this.otherCodegenBindings[index-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
 				}
-		    } if (index == 0){
-				this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
-			} else {
-				if (this.otherCodegenBindings == this.otherBindings){
-					int l = this.otherBindings.length;
-					System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l);
-				}
-				this.otherCodegenBindings[index-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType.erasure());
-			}
+			}		
 		}
 	}
-
 /**
  * Normal field binding did not work, try to bind to a field of the delegate receiver.
  */
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
index 7658691..e0ce276 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetReturnStatement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
index b1cffbe..b2512b2 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -243,7 +243,7 @@
 }
 // Internal use only
 public MethodBinding findExactMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
-	MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes);
+	MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, null);
 	if (exactMethod != null){
 		if (receiverType.isInterface() || canBeSeenByForCodeSnippet(exactMethod, receiverType, invocationSite, this))
 			return exactMethod;
@@ -475,7 +475,7 @@
 				candidates[0].declaringClass,
 				NotVisible);
 		}	
-		if (candidates[0].declaringClass.isClass()) {
+		if (!candidates[0].declaringClass.isInterface()) {
 			return mostSpecificClassMethodBinding(candidates, visiblesCount, invocationSite);
 		} else {
 			return mostSpecificInterfaceMethodBinding(candidates, visiblesCount, invocationSite);
@@ -485,7 +485,7 @@
 // Internal use only
 public MethodBinding findMethodForArray(ArrayBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
 	ReferenceBinding object = getJavaLangObject();
-	MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes);
+	MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes, null);
 	if (methodBinding != null) {
 		// handle the method clone() specially... cannot be protected or throw exceptions
 		if (argumentTypes == NoParameters && CharOperation.equals(selector, CLONE))
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
index 256a671..e73168b 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,6 +21,7 @@
 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -575,19 +576,26 @@
 	}		
 	if ((this.bits & Binding.FIELD) != 0) {
 		FieldBinding fieldBinding = (FieldBinding) this.binding;
+		
 		// if the binding declaring class is not visible, need special action
 		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
 		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
 		// and not from Object or implicit static field access.	
 		if (fieldBinding.declaringClass != this.delegateThis.type
-			&& fieldBinding.declaringClass != null
-			&& !fieldBinding.isConstantValue()
-			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2 
-					&& !fieldBinding.isStatic()
-					&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields (if there was any)
-				|| !((FieldBinding)this.codegenBinding).declaringClass.canBeSeenBy(currentScope))){
-			this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding((FieldBinding)this.codegenBinding, (ReferenceBinding)this.delegateThis.type.erasure());
-		}
+				&& fieldBinding.declaringClass != null // array.length
+				&& !fieldBinding.isConstantValue()) {
+			CompilerOptions options = currentScope.environment().options;
+			if ((options.targetJDK >= ClassFileConstants.JDK1_2
+					&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic())
+					&& fieldBinding.declaringClass.id != T_JavaLangObject) // no change for Object fields
+				|| !fieldBinding.declaringClass.canBeSeenBy(currentScope)) {
+	
+				this.codegenBinding = 
+				    currentScope.enclosingSourceType().getUpdatedFieldBinding(
+					       (FieldBinding)this.codegenBinding, 
+					        (ReferenceBinding)this.delegateThis.type.erasure());
+			}
+		}				
 	}
 }
 /**
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java
index 381a026..d53b9b4 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSkeleton.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java
index 46be4a4..db67ced 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetSuperReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java
index 6498553..38ce515 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetThisReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
index 9f36ecc..b2e7dbc 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -248,14 +248,8 @@
  */
 public ISelectionRequestor getSelectionRequestor(final ISelectionRequestor originalRequestor) {
 	return new ISelectionRequestor() {
-		public void acceptAnnotation(char[] packageName, char[] annotationName, boolean isDeclaration, char[] uniqueKey, int start, int end) {
-			originalRequestor.acceptAnnotation(packageName, annotationName, isDeclaration, uniqueKey, start, end);
-		}
-		public void acceptClass(char[] packageName, char[] className, boolean isDeclaration, char[] uniqueKey, int start, int end) {
-			originalRequestor.acceptClass(packageName, className, isDeclaration, uniqueKey, start, end);
-		}
-		public void acceptEnum(char[] packageName, char[] enumName, boolean isDeclaration, char[] uniqueKey, int start, int end) {
-			originalRequestor.acceptClass(packageName, enumName, isDeclaration, uniqueKey, start, end);
+		public void acceptType(char[] packageName, char[] typeName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+			originalRequestor.acceptType(packageName, typeName, modifiers, isDeclaration, uniqueKey, start, end);
 		}
 		public void acceptError(IProblem error) {
 			error.setSourceLineNumber(error.getSourceLineNumber() -  CodeSnippetToCuMapper.this.lineNumberOffset);
@@ -266,9 +260,6 @@
 		public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] name, boolean isDeclaration, char[] uniqueKey, int start, int end) {
 			originalRequestor.acceptField(declaringTypePackageName, declaringTypeName, name, isDeclaration, uniqueKey, start, end);
 		}
-		public void acceptInterface(char[] packageName, char[] interfaceName, boolean isDeclaration, char[] uniqueKey, int start, int end) {
-			originalRequestor.acceptInterface(packageName, interfaceName, isDeclaration, uniqueKey, start, end);
-		}
 		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, String enclosingDeclaringTypeSignature, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, boolean isConstructor, boolean isDeclaration, char[] uniqueKey, int start, int end) {
 			originalRequestor.acceptMethod(declaringTypePackageName, declaringTypeName, enclosingDeclaringTypeSignature, selector, parameterPackageNames, parameterTypeNames, parameterSignatures, isConstructor, isDeclaration, uniqueKey, start, end);
 		}
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
index 4492450..9a71948 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java
index 661bc53..0a88cf7 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
index d2414ec..893caf2 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java
index 47ed9e8..837a611 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/EvaluationResult.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java
index 5e1c26e..fa71047 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/Evaluator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java
index 5788bba..85f2ef1 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/GlobalVariable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java
index 8c444ac..651f0c4 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/IRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java
index 317bc2e..24e3981 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/InstallException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
index 48b15d0..f75da9a 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesEvaluator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java
index c60e777..f0227c7 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/VariablesInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
index f44709f..6004a42 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -44,6 +44,22 @@
 	 */
 	public static final int K_COMPILATION_UNIT = 0x08;
 
+	/**
+	 * Kind used to format a single-line comment
+	 * @since 3.1
+	 */
+	public static final int K_SINGLE_LINE_COMMENT = 0x10;
+	/**
+	 * Kind used to format a multi-line comment
+	 * @since 3.1
+	 */
+	public static final int K_MULTI_LINE_COMMENT = 0x20;
+	/**
+	 * Kind used to format a Javadoc comment
+	 * @since 3.1
+	 */
+	public static final int K_JAVA_DOC = 0x40;
+
 	/** 
 	 * Format <code>source</code>,
 	 * and returns a text edit that correspond to the difference between the given string and the formatted string.
@@ -53,7 +69,8 @@
 	 * caller to get rid of preceeding whitespaces.
 	 * 
 	 * @param kind Use to specify the kind of the code snippet to format. It can be any of these:
-	 * 		  K_EXPRESSION, K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_COMPILATION_UNIT, K_UNKNOWN
+	 *        K_EXPRESSION, K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_COMPILATION_UNIT, K_UNKNOWN,
+	 *        K_SINGLE_LINE_COMMENT, K_MULTI_LINE_COMMENT, K_JAVA_DOC
 	 * @param source the source to format
 	 * @param offset the given offset to start recording the edits (inclusive).
 	 * @param length the given length to stop recording the edits (exclusive).
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index f1b76ef..25823a2 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,11 +23,6 @@
  */
 public class DefaultCodeFormatterConstants {
 
-	/*
-	 * Private constants. Not in javadoc
-	 */
-	private static final IllegalArgumentException WRONG_ARGUMENT = new IllegalArgumentException();
-
 	/**
 	 * <pre>
 	 * FORMATTER / Value to set a brace location at the end of a line.
@@ -42,51 +37,6 @@
 	 * @since 3.0
 	 */
 	public static final String END_OF_LINE = "end_of_line";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Value to set a brace location at the start of the next line with
-	 *             the right indentation.
-	 * </pre>
-	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
-	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
-	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
-	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
- 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
- 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
-	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
-	 * @since 3.0
-	 */
-	public static final String NEXT_LINE = "next_line"; //$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Value to set a brace location at the start of the next line with
-	 *             an extra indentation.
-	 * </pre>
-	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
-	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
-	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
-	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
- 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
- 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
-	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
-	 * @since 3.0
-	 */
-	public static final String NEXT_LINE_SHIFTED = "next_line_shifted";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Value to set a brace location at the start of the next line if a wrapping
-	 *             occured.
-	 * </pre>
-	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
-	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
-	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
-	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
- 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
- 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
-	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
-	 * @since 3.0
-	 */
-    public static final String NEXT_LINE_ON_WRAP = "next_line_on_wrap"; //$NON-NLS-1$
 
 	/**
 	 * <pre>
@@ -94,82 +44,19 @@
 	 * </pre>
 	 * @since 3.0
 	 */
-    public static final String FALSE = "false"; //$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Value to set an option to false.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String TRUE = "true"; //$NON-NLS-1$
-
-	/**
-	 * <pre>
-	 * FORMATTER / Value to disable alignment.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int WRAP_NO_SPLIT= 0;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done using as few lines as possible.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int WRAP_COMPACT= 1;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done putting the first element on a new
-	 *             line and then wrapping next elements using as few lines as possible.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int WRAP_COMPACT_FIRST_BREAK= 2;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done by putting each element on its own line.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int WRAP_ONE_PER_LINE= 3;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done by putting each element on its own line.
-	 *             All elements are indented by one except the first element.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int WRAP_NEXT_SHIFTED= 4;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done by putting each element on its own line
-	 *             except the first element.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int WRAP_NEXT_PER_LINE= 5;
+	public static final String FALSE = "false"; //$NON-NLS-1$
 	
 	/**
 	 * <pre>
-	 * FORMATTER / The wrapping is done by using the current indentation.
+	 * FORMATTER / Option to align type members of a type declaration on column
+	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
+	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
 	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
 	 * @since 3.0
 	 */
-	public static final int INDENT_DEFAULT= 0;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done by indenting on column under the splitting location.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int INDENT_ON_COLUMN = 1;
-	/**
-	 * <pre>
-	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final int INDENT_BY_ONE= 2;
+	public static final String FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS = JavaCore.PLUGIN_ID + ".formatter.align_type_members_on_columns";	 //$NON-NLS-1$
 	
 	/**
 	 * <pre>
@@ -261,6 +148,17 @@
 	public static final String FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_conditional_expression";	 //$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option for alignment of enum constants
+	 *     - option id:        "org.eclipse.jdt.core.formatter.alignment_for_enum_constants"
+	 *     - possible values:  values returned by <code>createAlignmentValue(boolean, int, int)</code> call
+	 *     - default:          createAlignmentValue(false, WRAP_NO_SPLIT, INDENT_DEFAULT)
+	 * </pre>
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS = JavaCore.PLUGIN_ID + ".formatter.alignment_for_enum_constants";	 //$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option for alignment of expressions in array initializer
 	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer"
 	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
@@ -369,18 +267,117 @@
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.alignment_for_throws_clause_in_method_declaration";	 //$NON-NLS-1$
-	
+
 	/**
 	 * <pre>
-	 * FORMATTER / Option to align type members of a type declaration on column
-	 *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration"
-	 *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
-	 *     - default:           createAlignmentValue(false, WRAP_COMPACT, INDENT_DEFAULT)
+	 * FORMATTER / Option to add blank lines after the imports declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_after_imports"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
 	 * </pre>
-	 * @see #createAlignmentValue(boolean, int, int)
 	 * @since 3.0
 	 */
-	public static final String FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS = JavaCore.PLUGIN_ID + ".formatter.align_type_members_on_columns";	 //$NON-NLS-1$
+	public static final String FORMATTER_BLANK_LINES_AFTER_IMPORTS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_after_imports";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines after the package declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_after_package"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_AFTER_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_after_package";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines at the beginning of the method body
+	 *     - option id:         "org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY = JavaCore.PLUGIN_ID + ".formatter.number_of_blank_lines_at_beginning_of_method_body"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a field declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_field"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_FIELD = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_field";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before the first class body declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_first_class_body_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before the imports declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_imports"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_IMPORTS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_imports";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a member type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_member_type"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_member_type";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_method"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_METHOD = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_method";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before a new chunk
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_new_chunk";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines before the package declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_package"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BEFORE_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_package";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to add blank lines between type declarations
+	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "0"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_between_type_declarations";	//$NON-NLS-1$
 	/**
 	 * <pre>
 	 * FORMATTER / Option to position the braces of an annotation type declaration
@@ -510,20 +507,6 @@
 	public static final String FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_method_declaration";	//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to position the braces of a type declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"
-	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
-	 *     - default:           END_OF_LINE
-	 * </pre>
-	 * @see #END_OF_LINE
-	 * @see #NEXT_LINE
-	 * @see #NEXT_LINE_SHIFTED
-	 * @see #NEXT_LINE_ON_WRAP
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_type_declaration";	//$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to position the braces of a switch statement
 	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_switch"
 	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
@@ -536,6 +519,161 @@
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_BRACE_POSITION_FOR_SWITCH = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_switch";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to position the braces of a type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.brace_position_for_type_declaration"
+	 *     - possible values:   { END_OF_LINE, NEXT_LINE, NEXT_LINE_SHIFTED, NEXT_LINE_ON_WRAP }
+	 *     - default:           END_OF_LINE
+	 * </pre>
+	 * @see #END_OF_LINE
+	 * @see #NEXT_LINE
+	 * @see #NEXT_LINE_SHIFTED
+	 * @see #NEXT_LINE_ON_WRAP
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.brace_position_for_type_declaration";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether blank lines are cleared inside comments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.clear_blank_lines"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines"; //$NON-NLS-1$
+	
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether comments are formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_comments"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_FORMAT = "org.eclipse.jdt.core.formatter.comment.format_comments"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether the header comment of a Java source file is formatted
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_header"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_FORMAT_HEADER = "org.eclipse.jdt.core.formatter.comment.format_header"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether HTML tags are formatted.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_html"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_FORMAT_HTML = "org.eclipse.jdt.core.formatter.comment.format_html"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether code snippets are formatted in comments
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.format_source_code"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_FORMAT_SOURCE = "org.eclipse.jdt.core.formatter.comment.format_source_code"; //$NON-NLS-1$
+	
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether description of Javadoc parameters are indented
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.indent_parameter_description"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION = "org.eclipse.jdt.core.formatter.comment.indent_parameter_description"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control whether Javadoc root tags are indented.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.indent_root_tags"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_INDENT_ROOT_TAGS = "org.eclipse.jdt.core.formatter.comment.indent_root_tags"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert an empty line before the Javadoc root tag block
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS = "org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after Javadoc root tag parameters
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER = "org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to specify the line length for comments.
+	 *     - option id:         "org.eclipse.jdt.core.formatter.comment.line_length"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "80"
+	 * </pre>
+	 * @since 3.1
+	 */	
+	public final static String FORMATTER_COMMENT_LINE_LENGTH = "org.eclipse.jdt.core.formatter.comment.line_length"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to compact else/if
+	 *     - option id:         "org.eclipse.jdt.core.formatter.compact_else_if"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           TRUE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_COMPACT_ELSE_IF = JavaCore.PLUGIN_ID + ".formatter.compact_else_if";	//$NON-NLS-1$
 
 	/**
 	 * <pre>
@@ -557,117 +695,6 @@
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.continuation_indentation_for_array_initializer";	//$NON-NLS-1$
-
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines after the imports declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_after_imports"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_AFTER_IMPORTS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_after_imports";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines after the package declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_after_package"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_AFTER_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_after_package";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before a field declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_field"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_FIELD = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_field";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before the first class body declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_FIRST_CLASS_BODY_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_first_class_body_declaration";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before the imports declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_imports"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_IMPORTS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_imports";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before a member type declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_member_type"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_MEMBER_TYPE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_member_type";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before a method declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_method"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_METHOD = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_method";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before a new chunk
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_NEW_CHUNK = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_new_chunk";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines before the package declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_before_package"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BEFORE_PACKAGE = JavaCore.PLUGIN_ID + ".formatter.blank_lines_before_package";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines between type declarations
-	 *     - option id:         "org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_BETWEEN_TYPE_DECLARATIONS = JavaCore.PLUGIN_ID + ".formatter.blank_lines_between_type_declarations";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to add blank lines at the beginning of the method body
-	 *     - option id:         "org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "0"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY = JavaCore.PLUGIN_ID + ".formatter.number_of_blank_lines_at_beginning_of_method_body"; //$NON-NLS-1$
 	/**
 	 * <pre>
 	 * FORMATTER / Option to indent body declarations compare to its enclosing enum constant header
@@ -767,6 +794,33 @@
 
 	/**
 	 * <pre>
+	 * FORMATTER / Option to specify the equivalent number of spaces that represents one indentation 
+	 *     - option id:         "org.eclipse.jdt.core.formatter.indentation.size"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "4"
+	 * </pre>
+	 * <p>This option is used only if the tab char is set to MIXED.
+	 * </p>
+	 * @see #FORMATTER_TAB_CHAR
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INDENTATION_SIZE = JavaCore.PLUGIN_ID + ".formatter.indentation.size"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / Option to insert a new line after the opening brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation";//$NON-NLS-1$
+
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a new line after the opening brace in an array initializer
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1008,18 +1062,6 @@
 	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_angle_bracket_in_type_parameters"; //$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space after the closing parenthesis of a cast expression
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_paren_in_cast"; //$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to insert a space after the closing brace of a block
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1032,6 +1074,18 @@
 	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_brace_in_block"; //$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a space after the closing parenthesis of a cast expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_closing_paren_in_cast"; //$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a space after the colon in an assert statement
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1212,18 +1266,6 @@
 	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_FOR_INITS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_for_inits"; //$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space after the comma in the arguments of a method invocation
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_invocation_arguments"; //$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to insert a space after the comma in the parameters of a method declaration
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1248,6 +1290,18 @@
 	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_declaration_throws"; //$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a space after the comma in the arguments of a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_invocation_arguments"; //$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a space after the comma in multiple field declaration
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1368,6 +1422,18 @@
 	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_TYPE_PARAMETERS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_angle_bracket_in_type_parameters";//$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a space after the opening brace in an array initializer
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_brace_in_array_initializer";	//$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a space after the opening bracket inside an array allocation expression
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1392,18 +1458,6 @@
 	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_bracket_in_array_reference";//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space after the opening brace in an array initializer
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           DO_NOT_INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_brace_in_array_initializer";	//$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to insert a space after the opening parenthesis in annotation
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1644,18 +1698,6 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_AND_IN_TYPE_PARAMETER = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_and_in_type_parameter";	//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space before at in annotation type declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.1
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_AT_IN_ANNOTATION_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_at_in_annotation_type_declaration";	//$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to insert a space before an assignment operator
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -1668,6 +1710,18 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_assignment_operator";	//$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a space before at in annotation type declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_AT_IN_ANNOTATION_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_at_in_annotation_type_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a space before an binary operator
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_binary_operator"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -2100,18 +2154,6 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_FOR_INITS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_for_inits";	//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space before comma in the arguments of a method invocation
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           DO_NOT_INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_invocation_arguments";	//$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to insert a space before comma in the parameters of a method declaration
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -2136,6 +2178,18 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_declaration_throws";	//$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a space before comma in the arguments of a method invocation
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_invocation_arguments";	//$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a space before comma in a multiple field declaration
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -2496,6 +2550,18 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_if";	//$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a method declaration
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
+	 *     - possible values:   { INSERT, DO_NOT_INSERT }
+	 *     - default:           DO_NOT_INSERT
+	 * </pre>
+	 * @see JavaCore#INSERT
+	 * @see JavaCore#DO_NOT_INSERT
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_declaration";	//$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to insert a space before the opening parenthesis in a method invocation
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -2508,8 +2574,8 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_invocation";	//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space before the opening parenthesis in a method declaration
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
+	 * FORMATTER / Option to insert a space before the opening parenthesis in a parenthesized expression
+	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
 	 *     - default:           DO_NOT_INSERT
 	 * </pre>
@@ -2517,7 +2583,7 @@
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.0
 	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_method_declaration";	//$NON-NLS-1$
+	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_parenthesized_expression"; //$NON-NLS-1$
 	/**
 	 * <pre>
 	 * FORMATTER / Option to insert a space before the opening parenthesis in a switch statement
@@ -2544,18 +2610,6 @@
 	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SYNCHRONIZED = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_synchronized";	//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to insert a space before the opening parenthesis in a parenthesized expression
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           DO_NOT_INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_paren_in_parenthesized_expression"; //$NON-NLS-1$
-	/**
-	 * <pre>
 	 * FORMATTER / Option to insert a space before the opening parenthesis in a while statement
 	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while"
 	 *     - possible values:   { INSERT, DO_NOT_INSERT }
@@ -2747,31 +2801,6 @@
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_parens_in_method_invocation";	//$NON-NLS-1$
-
-	/**
-	 * <pre>
-	 * FORMATTER / Option to compact else/if
-	 *     - option id:         "org.eclipse.jdt.core.formatter.compact_else_if"
-	 *     - possible values:   { TRUE, FALSE }
-	 *     - default:           TRUE
-	 * </pre>
-	 * @see #TRUE
-	 * @see #FALSE
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_COMPACT_ELSE_IF = JavaCore.PLUGIN_ID + ".formatter.compact_else_if";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to keep guardian clause on one line
-	 *     - option id:         "org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
-	 *     - possible values:   { TRUE, FALSE }
-	 *     - default:           FALSE
-	 * </pre>
-	 * @see #TRUE
-	 * @see #FALSE
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line";	//$NON-NLS-1$
 	/**
 	 * <pre>
 	 * FORMATTER / Option to keep else statement on the same line
@@ -2798,6 +2827,18 @@
 	public static final String FORMATTER_KEEP_EMPTY_ARRAY_INITIALIZER_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_empty_array_initializer_on_one_line"; //$NON-NLS-1$
 	/**
 	 * <pre>
+	 * FORMATTER / Option to keep guardian clause on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line";	//$NON-NLS-1$
+	/**
+	 * <pre>
 	 * FORMATTER / Option to keep simple if statement on the one line
 	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line"
 	 *     - possible values:   { TRUE, FALSE }
@@ -2823,6 +2864,17 @@
 
 	/**
 	 * <pre>
+	 * FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
+	 *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
+	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
+	 *     - default:           "80"
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_LINE_SPLIT = JavaCore.PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
 	 * FORMATTER / Option to specify the number of empty lines to preserve
 	 *     - option id:         "org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve"
 	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
@@ -2843,32 +2895,24 @@
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE = JavaCore.PLUGIN_ID + ".formatter.put_empty_statement_on_new_line";	//$NON-NLS-1$
-
-	/**
-	 * <pre>
-	 * FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
-	 *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
-	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
-	 *     - default:           "80"
-	 * </pre>
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_LINE_SPLIT = JavaCore.PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
 	/**
 	 * <pre>
 	 * FORMATTER / Option to specify the tabulation size
-	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.size"
-	 *     - possible values:   { TAB, SPACE }
+	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.char"
+	 *     - possible values:   { TAB, SPACE, MIXED }
 	 *     - default:           TAB
 	 * </pre>
+	 * More values may be added in the future.
+	 * 
 	 * @see JavaCore#TAB
 	 * @see JavaCore#SPACE
+	 * @see #MIXED
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_TAB_CHAR = JavaCore.PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to specify the tabulation size
+	 * FORMATTER / Option to specify the equivalent number of spaces that represents one tabulation 
 	 *     - option id:         "org.eclipse.jdt.core.formatter.tabulation.size"
 	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
 	 *     - default:           "4"
@@ -2878,6 +2922,198 @@
 	public static final String FORMATTER_TAB_SIZE = JavaCore.PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
 
 	/**
+	 * <pre>
+	 * FORMATTER / Option to use tabulations only for leading indentations 
+	 *     - option id:         "org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * <p>This is used only if the {@link #FORMATTER_TAB_CHAR } is set to {@link JavaCore#TAB}.</p>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @since 3.1
+	 */
+	public static final String FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS = JavaCore.PLUGIN_ID + ".formatter.use_tabs_only_for_leading_indentations"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by indenting by one compare to the current indentation.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int INDENT_BY_ONE= 2;
+	
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by using the current indentation.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int INDENT_DEFAULT= 0;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by indenting on column under the splitting location.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int INDENT_ON_COLUMN = 1;
+	
+	/**
+	 * <pre>
+	 * FORMATTER / Possible value for the option FORMATTER_TAB_CHAR
+	 * </pre>
+	 * @since 3.1
+	 * @see JavaCore#TAB
+	 * @see JavaCore#SPACE
+	 * @see #FORMATTER_TAB_CHAR
+	 */
+	public static final String MIXED = "mixed"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the start of the next line with
+	 *             the right indentation.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @since 3.0
+	 */
+	public static final String NEXT_LINE = "next_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the start of the next line if a wrapping
+	 *             occured.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @since 3.0
+	 */
+    public static final String NEXT_LINE_ON_WRAP = "next_line_on_wrap"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set a brace location at the start of the next line with
+	 *             an extra indentation.
+	 * </pre>
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION
+	 * @see #FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER
+	 * @see #FORMATTER_BRACE_POSITION_FOR_BLOCK
+	 * @see #FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION
+ 	 * @see #FORMATTER_BRACE_POSITION_FOR_SWITCH
+	 * @see #FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION
+	 * @since 3.0
+	 */
+	public static final String NEXT_LINE_SHIFTED = "next_line_shifted";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to set an option to false.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final String TRUE = "true"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done using as few lines as possible.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_COMPACT= 1;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done putting the first element on a new
+	 *             line and then wrapping next elements using as few lines as possible.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_COMPACT_FIRST_BREAK= 2;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by putting each element on its own line
+	 *             except the first element.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_NEXT_PER_LINE= 5;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by putting each element on its own line.
+	 *             All elements are indented by one except the first element.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_NEXT_SHIFTED= 4;
+
+	/**
+	 * <pre>
+	 * FORMATTER / Value to disable alignment.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_NO_SPLIT= 0;
+	/**
+	 * <pre>
+	 * FORMATTER / The wrapping is done by putting each element on its own line.
+	 * </pre>
+	 * @since 3.0
+	 */
+	public static final int WRAP_ONE_PER_LINE= 3;
+
+	/*
+	 * Private constants. Not in javadoc
+	 */
+	private static final IllegalArgumentException WRONG_ARGUMENT = new IllegalArgumentException();
+	/**
+	 * 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) {
+			case WRAP_COMPACT :
+				alignmentValue |= Alignment.M_COMPACT_SPLIT;
+				break;
+			case WRAP_COMPACT_FIRST_BREAK :
+				alignmentValue |= Alignment.M_COMPACT_FIRST_BREAK_SPLIT;
+				break;
+			case WRAP_NEXT_PER_LINE :
+				alignmentValue |= Alignment.M_NEXT_PER_LINE_SPLIT;
+				break;
+			case WRAP_NEXT_SHIFTED :
+				alignmentValue |= Alignment.M_NEXT_SHIFTED_SPLIT;
+				break;
+			case WRAP_ONE_PER_LINE :
+				alignmentValue |= Alignment.M_ONE_PER_LINE_SPLIT;
+				break;
+		}		
+		if (forceSplit) {
+			alignmentValue |= Alignment.M_FORCE;
+		}
+		switch(indentStyle) {
+			case INDENT_BY_ONE :
+				alignmentValue |= Alignment.M_INDENT_BY_ONE;
+				break;
+			case INDENT_ON_COLUMN :
+				alignmentValue |= Alignment.M_INDENT_ON_COLUMN;
+		}
+		return String.valueOf(alignmentValue);
+	}
+
+	/**
 	 * Returns the formatter settings that most closely approximate
 	 * the default formatter settings of Eclipse version 2.1.
 	 * 
@@ -2889,13 +3125,13 @@
 	}
 
 	/**
-	 * Returns the settings according to the Java conventions.
+	 * Returns the default Eclipse formatter settings
 	 * 
-	 * @return the settings according to the Java conventions
-	 * @since 3.0
+	 * @return the Eclipse default settings
+	 * @since 3.1
 	 */
-	public static Map getJavaConventionsSettings() {
-		return DefaultCodeFormatterOptions.getJavaConventionsSettings().getMap();
+	public static Map getEclipseDefaultSettings() {
+		return DefaultCodeFormatterOptions.getEclipseDefaultSettings().getMap();
 	}
 
 	/**
@@ -2951,6 +3187,16 @@
 			throw WRONG_ARGUMENT;
 		}
 	}
+
+	/**
+	 * Returns the settings according to the Java conventions.
+	 * 
+	 * @return the settings according to the Java conventions
+	 * @since 3.0
+	 */
+	public static Map getJavaConventionsSettings() {
+		return DefaultCodeFormatterOptions.getJavaConventionsSettings().getMap();
+	}
 	/**
 	 * <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>
@@ -2987,6 +3233,35 @@
 			throw WRONG_ARGUMENT;
 		}
 	}
+	/**
+	 * <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.
+	 * </p>
+	 *
+	 * @param value the given alignment value
+	 * @param force the given force value
+	 * @return the new alignment value
+	 * @see #createAlignmentValue(boolean, int, int)
+	 * @exception IllegalArgumentException if the given alignment value is null, or if it 
+	 * doesn't have a valid format.
+	 */
+	public static String setForceWrapping(String value, boolean force) {
+		if (value == null) {
+			throw WRONG_ARGUMENT;
+		}
+		try {
+			int existingValue = Integer.parseInt(value);
+			// clear existing force bit
+			existingValue &= ~Alignment.M_FORCE;
+			if (force) {
+				existingValue |= Alignment.M_FORCE;
+			}
+			return String.valueOf(existingValue);
+		} catch (NumberFormatException e) {
+			throw WRONG_ARGUMENT;
+		}		
+	}
 	
 	/**
 	 * <p>Set the indentation style of the given alignment value and return the new value.
@@ -3034,35 +3309,6 @@
 		}
 	}
 	/**
-	 * <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.
-	 * </p>
-	 *
-	 * @param value the given alignment value
-	 * @param force the given force value
-	 * @return the new alignment value
-	 * @see #createAlignmentValue(boolean, int, int)
-	 * @exception IllegalArgumentException if the given alignment value is null, or if it 
-	 * doesn't have a valid format.
-	 */
-	public static String setForceWrapping(String value, boolean force) {
-		if (value == null) {
-			throw WRONG_ARGUMENT;
-		}
-		try {
-			int existingValue = Integer.parseInt(value);
-			// clear existing force bit
-			existingValue &= ~Alignment.M_FORCE;
-			if (force) {
-				existingValue |= Alignment.M_FORCE;
-			}
-			return String.valueOf(existingValue);
-		} catch (NumberFormatException e) {
-			throw WRONG_ARGUMENT;
-		}		
-	}
-	/**
 	 * <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>
 	 * API.
@@ -3123,45 +3369,4 @@
 			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) {
-			case WRAP_COMPACT :
-				alignmentValue |= Alignment.M_COMPACT_SPLIT;
-				break;
-			case WRAP_COMPACT_FIRST_BREAK :
-				alignmentValue |= Alignment.M_COMPACT_FIRST_BREAK_SPLIT;
-				break;
-			case WRAP_NEXT_PER_LINE :
-				alignmentValue |= Alignment.M_NEXT_PER_LINE_SPLIT;
-				break;
-			case WRAP_NEXT_SHIFTED :
-				alignmentValue |= Alignment.M_NEXT_SHIFTED_SPLIT;
-				break;
-			case WRAP_ONE_PER_LINE :
-				alignmentValue |= Alignment.M_ONE_PER_LINE_SPLIT;
-				break;
-		}		
-		if (forceSplit) {
-			alignmentValue |= Alignment.M_FORCE;
-		}
-		switch(indentStyle) {
-			case INDENT_BY_ONE :
-				alignmentValue |= Alignment.M_INDENT_BY_ONE;
-				break;
-			case INDENT_ON_COLUMN :
-				alignmentValue |= Alignment.M_INDENT_ON_COLUMN;
-		}
-		return String.valueOf(alignmentValue);
-	}
 }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java
index 48d702f..4f66a36 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/AbortFormatting.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 /**
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java
index 474e68a..331746c 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/BinaryExpressionFragmentBuilder.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 import java.util.ArrayList;
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
 import org.eclipse.jdt.internal.compiler.ast.CastExpression;
 import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
 import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
 import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
 import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
@@ -259,6 +260,13 @@
 	}
 
 	public boolean visit(
+		ClassLiteralAccess classLiteralAccess,
+		BlockScope scope) {
+			this.addRealFragment(classLiteralAccess);
+			return false;
+	}
+	
+	public boolean visit(
 		CompoundAssignment compoundAssignment,
 		BlockScope scope) {
 			this.addRealFragment(compoundAssignment);
@@ -327,13 +335,18 @@
 	}
 
 	public boolean visit(StringLiteralConcatenation stringLiteral, BlockScope scope) {
-		for (int i = 0, max = stringLiteral.counter; i < max; i++) {
-			this.addRealFragment(stringLiteral.literals[i]);
-			if (i < max - 1) {
-				this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+		if (((stringLiteral.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+			addRealFragment(stringLiteral);
+			return false;
+		} else {
+			for (int i = 0, max = stringLiteral.counter; i < max; i++) {
+				this.addRealFragment(stringLiteral.literals[i]);
+				if (i < max - 1) {
+					this.operatorsList.add(new Integer(TerminalTokens.TokenNamePLUS));
+				}
 			}
+			return false;
 		}
-		return false;
 	}
 	
 	public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java
index f3de4d1..6c70907 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CascadingMethodInvocationFragmentBuilder.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 import java.util.ArrayList;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
index ea3a5f3..2211187 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/CodeFormatterVisitor.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2002, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2002, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 import java.util.ArrayList;
@@ -115,6 +115,7 @@
 import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
 import org.eclipse.jdt.internal.formatter.align.Alignment;
 import org.eclipse.jdt.internal.formatter.align.AlignmentException;
+import org.eclipse.jdt.internal.formatter.comment.CommentRegion;
 import org.eclipse.text.edits.TextEdit;
 
 /**
@@ -828,6 +829,38 @@
 		return this.scribe.getRootEdit();
 	}
 	
+	/**
+	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, String, int, int, int, String)
+	 */
+	public TextEdit format(String string, CommentRegion region) {
+		// reset the scribe
+		this.scribe.reset();
+		
+		if (region == null) {
+			return failedToFormat();
+		}
+
+		long startTime = 0;
+		if (DEBUG){
+			startTime = System.currentTimeMillis();
+		}
+
+		final char[] compilationUnitSource = string.toCharArray();
+		
+		this.scribe.initializeScanner(compilationUnitSource);
+
+		TextEdit result = null;
+		try {
+			result = region.format(this.preferences.initial_indentation_level, true);
+		} catch(AbortFormatting e){
+			return failedToFormat();
+		}
+		if (DEBUG){
+			System.out.println("Formatting time: " + (System.currentTimeMillis() - startTime));  //$NON-NLS-1$
+		}
+		return result;
+	}
+
 	private void format(TypeDeclaration typeDeclaration){
         /*
          * Print comments to get proper line number
@@ -1002,15 +1035,52 @@
 			boolean hasConstants = false;
 			if (fieldDeclarations != null) {
 				int length = fieldDeclarations.length;
-				loop: for (int i = 0; i < length; i++) {
+				int enumConstantsLength = 0;
+				for (int i = 0; i < length; i++) {
 					FieldDeclaration fieldDeclaration = fieldDeclarations[i];
-					if (fieldDeclaration.getKind() != AbstractVariableDeclaration.ENUM_CONSTANT) {
-						break loop;
+					if (fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+						enumConstantsLength++;
+					} else {
+						break;
 					}
-					if (i < length) {
-						hasConstants = true;
-						fieldDeclaration.traverse(this, typeDeclaration.initializerScope);
-					}
+				}
+				hasConstants = enumConstantsLength != 0;
+				if (enumConstantsLength > 1) {
+					Alignment enumConstantsAlignment = this.scribe.createAlignment(
+							"enumConstants",//$NON-NLS-1$
+							this.preferences.alignment_for_enum_constants,
+							enumConstantsLength,
+							this.scribe.scanner.currentPosition,
+							0, // we don't want to indent enum constants when splitting to a new line
+							false);
+					this.scribe.enterAlignment(enumConstantsAlignment);
+					boolean ok = false;
+					do {
+						try {
+							for (int i = 0; i < enumConstantsLength; i++) {
+								this.scribe.alignFragment(enumConstantsAlignment, i);
+								FieldDeclaration fieldDeclaration = fieldDeclarations[i];
+								fieldDeclaration.traverse(this, typeDeclaration.initializerScope);
+								if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
+									this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_enum_declarations);
+									if (this.preferences.insert_space_after_comma_in_enum_declarations) {
+										this.scribe.space();
+									}
+									this.scribe.printTrailingComment();
+									if (fieldDeclaration.initialization instanceof QualifiedAllocationExpression) {
+										this.scribe.printNewLine();
+									}
+								}
+							}
+							ok = true;
+						} catch (AlignmentException e) {
+							this.scribe.redoAlignment(e);
+						}
+					} while (!ok);
+					this.scribe.exitAlignment(enumConstantsAlignment, true);
+				} else {
+					FieldDeclaration fieldDeclaration = fieldDeclarations[0];
+					fieldDeclaration.traverse(this, typeDeclaration.initializerScope);
 					if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
 						this.scribe.printNextToken(TerminalTokens.TokenNameCOMMA, this.preferences.insert_space_before_comma_in_enum_declarations);
 						if (this.preferences.insert_space_after_comma_in_enum_declarations) {
@@ -1021,7 +1091,7 @@
 							this.scribe.printNewLine();
 						}
 					}
-				}			
+				}
 			}
 			if (isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
 				this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
@@ -1381,6 +1451,7 @@
 	private void formatEmptyTypeDeclaration(boolean isFirst) {
 		boolean hasSemiColon = isNextToken(TerminalTokens.TokenNameSEMICOLON);
 		while(isNextToken(TerminalTokens.TokenNameSEMICOLON)) {
+			this.scribe.printComment();
 			this.scribe.printNextToken(TerminalTokens.TokenNameSEMICOLON, this.preferences.insert_space_before_semicolon);
 			this.scribe.printTrailingComment();
 		}
@@ -2085,9 +2156,10 @@
 				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
 					this.scribe.space();
 				}
+		} else {
+			this.scribe.space();
 		}
 
-		this.scribe.space();
 		allocationExpression.type.traverse(this, scope);
 		
 		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
@@ -2204,7 +2276,7 @@
 
 		/*
 		 * Argument type 
-		 */		
+		 */
 		if (argument.type != null) {
 			argument.type.traverse(this, scope);
 		}
@@ -2350,6 +2422,8 @@
 				// we don't need to use an alignment
 				if (this.preferences.insert_space_after_opening_brace_in_array_initializer) {
 					this.scribe.space();
+				} else {
+					this.scribe.needSpace = false;
 				}
 				expressions[0].traverse(this, scope);
 				if (isNextToken(TerminalTokens.TokenNameCOMMA)) {
@@ -2374,15 +2448,13 @@
 			String array_initializer_brace_position = this.preferences.brace_position_for_array_initializer;
 			if (keepEmptyArrayInitializerOnTheSameLine) {
 				this.scribe.printNextToken(TerminalTokens.TokenNameLBRACE, this.preferences.insert_space_before_opening_brace_in_array_initializer);
+				this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, this.preferences.insert_space_between_empty_braces_in_array_initializer); 
 			} else {
 				formatOpeningBrace(array_initializer_brace_position, this.preferences.insert_space_before_opening_brace_in_array_initializer);
-			}
-			if (this.preferences.insert_space_between_empty_braces_in_array_initializer) {
-				this.scribe.space();
-			}
-			this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, false); 
-			if (keepEmptyArrayInitializerOnTheSameLine && array_initializer_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
-				this.scribe.unIndent();
+				this.scribe.printNextToken(TerminalTokens.TokenNameRBRACE, false); 
+				if (array_initializer_brace_position.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) {
+					this.scribe.unIndent();
+				}
 			}
 		}
 	
@@ -2737,7 +2809,8 @@
 		/* 
 		 * Package declaration
 		 */
-		if (compilationUnitDeclaration.currentPackage != null) {
+		final boolean hasPackage = compilationUnitDeclaration.currentPackage != null;
+		if (hasPackage) {
 			if (hasComments()) {
 				this.scribe.printComment();
 			}
@@ -2769,9 +2842,11 @@
 		 */
 		final ImportReference[] imports = compilationUnitDeclaration.imports;
 		if (imports != null) {
-			int blankLinesBeforeImports = this.preferences.blank_lines_before_imports;
-			if (blankLinesBeforeImports > 0) {
-				this.scribe.printEmptyLines(blankLinesBeforeImports);
+			if (hasPackage) {
+				int blankLinesBeforeImports = this.preferences.blank_lines_before_imports;
+				if (blankLinesBeforeImports > 0) {
+					this.scribe.printEmptyLines(blankLinesBeforeImports);
+				}
 			}
 			int importLength = imports.length;
 			for (int i = 0; i < importLength; i++) {
@@ -2795,7 +2870,6 @@
 			int typesLength = types.length;
 			for (int i = 0; i < typesLength - 1; i++) {
 				types[i].traverse(this, scope);
-				this.scribe.printComment();
 				formatEmptyTypeDeclaration(false);
 				if (blankLineBetweenTypeDeclarations != 0) {
 					this.scribe.printEmptyLines(blankLineBetweenTypeDeclarations);
@@ -3156,7 +3230,7 @@
         final int line = this.scribe.line; 
         
         this.scribe.printModifiers(enumConstant.annotations, this);
-		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, true); 
+		this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier, false); 
 		formatEnumConstantArguments(
 			enumConstant,
 			this.preferences.insert_space_before_opening_paren_in_enum_constant,
@@ -4075,7 +4149,7 @@
 				this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
 			}
 		}
-		int dimensions = parameterizedQualifiedTypeReference.dimensions();
+		int dimensions = getDimensions();
 		if (dimensions != 0) {
 			if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) {
 				this.scribe.space();
@@ -4102,7 +4176,7 @@
 		}
 		TypeReference[][] typeArguments = parameterizedQualifiedTypeReference.typeArguments;
 		int length = typeArguments.length;
-		for (int i = 0; i < length - 1; i++) {
+		for (int i = 0; i < length; i++) {
 			this.scribe.printNextToken(TerminalTokens.TokenNameIdentifier);
 			TypeReference[] typeArgument = typeArguments[i];			
 			if (typeArgument != null) {
@@ -4122,10 +4196,12 @@
 				if (isClosingGenericToken()) {
 					this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
 				}
-			}			
-			this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+			}
+			if (i < length - 1) {
+				this.scribe.printNextToken(TerminalTokens.TokenNameDOT);
+			}
 		}
-		int dimensions = parameterizedQualifiedTypeReference.dimensions();
+		int dimensions = getDimensions();
 		if (dimensions != 0) {
 			if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) {
 				this.scribe.space();
@@ -4169,7 +4245,7 @@
 		if (isClosingGenericToken()) {
 			this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
 		}
-		int dimensions = parameterizedSingleTypeReference.dimensions;
+		int dimensions = getDimensions();
 		if (dimensions != 0) {
 			if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) {
 				this.scribe.space();
@@ -4213,7 +4289,7 @@
 		if (isClosingGenericToken()) {
 			this.scribe.printNextToken(CLOSING_GENERICS_EXPECTEDTOKENS, this.preferences.insert_space_before_closing_angle_bracket_in_parameterized_type_reference);
 		}
-		int dimensions = parameterizedSingleTypeReference.dimensions;
+		int dimensions = getDimensions();
 		if (dimensions != 0) {
 			if (this.preferences.insert_space_before_opening_bracket_in_array_type_reference) {
 				this.scribe.space();
@@ -4318,10 +4394,11 @@
 				if (this.preferences.insert_space_after_closing_angle_bracket_in_type_arguments) {
 					this.scribe.space();
 				}
+		} else {
+			this.scribe.space();
 		}
 
 		final int line = this.scribe.line;
-		this.scribe.space();
 		qualifiedAllocationExpression.type.traverse(this, scope);
 		
 		this.scribe.printNextToken(TerminalTokens.TokenNameLPAREN, this.preferences.insert_space_before_opening_paren_in_method_invocation);
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index ab8b7e4..525bd59 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -1,18 +1,20 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 import java.util.HashMap;
 import java.util.Map;
 
+import org.eclipse.jdt.core.compiler.ITerminalSymbols;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.core.formatter.CodeFormatter;
 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.jdt.core.JavaCore;
@@ -20,20 +22,52 @@
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.parser.Scanner;
 import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil;
+import org.eclipse.jdt.internal.formatter.comment.CommentRegion;
+import org.eclipse.jdt.internal.formatter.comment.JavaDocRegion;
+import org.eclipse.jdt.internal.formatter.comment.MultiCommentRegion;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.text.edits.MultiTextEdit;
 import org.eclipse.text.edits.TextEdit;
 
 public class DefaultCodeFormatter extends CodeFormatter {
 
+	private static Scanner ProbingScanner;
 	public static final boolean DEBUG = false;
+
+	/**
+	 * Creates a comment region for a specific document partition type.
+	 * 
+	 * @param kind the comment snippet kind
+	 * @param document the document which contains the comment region
+	 * @param range range of the comment region in the document
+	 * @return a new comment region for the comment region range in the
+	 *         document
+	 * @since 3.1
+	 */
+	public static CommentRegion createRegion(int kind, IDocument document, Position range, CodeFormatterVisitor formatter) {
+		switch (kind) {
+			case CodeFormatter.K_SINGLE_LINE_COMMENT:
+				return new CommentRegion(document, range, formatter);
+			case CodeFormatter.K_MULTI_LINE_COMMENT:
+				return new MultiCommentRegion(document, range, formatter);
+			case CodeFormatter.K_JAVA_DOC:
+				return new JavaDocRegion(document, range, formatter);
+		}
+		return null;
+	}
+	private CodeSnippetParsingUtil codeSnippetParsingUtil;
+	private Map defaultCompilerOptions;
 	
 	private CodeFormatterVisitor newCodeFormatter;
 	private Map options;
-	private Map defaultCompilerOptions;
 	
 	private DefaultCodeFormatterOptions preferences;
-	private CodeSnippetParsingUtil codeSnippetParsingUtil;
 	
 	public DefaultCodeFormatter() {
 		this(new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getJavaConventionsSettings()), null);
@@ -60,7 +94,7 @@
 	public DefaultCodeFormatter(Map options) {
 		this(null, options);
 	}
-
+	
 	/**
 	 * @see org.eclipse.jdt.core.formatter.CodeFormatter#format(int, java.lang.String, int, int, int, java.lang.String)
 	 */
@@ -87,6 +121,10 @@
 				return formatStatements(source, indentationLevel, lineSeparator, offset, length);
 			case K_UNKNOWN :
 				return probeFormatting(source, indentationLevel, lineSeparator, offset, length);
+			case K_JAVA_DOC :
+			case K_MULTI_LINE_COMMENT :
+			case K_SINGLE_LINE_COMMENT :
+				return formatComment(kind, source, indentationLevel, lineSeparator, offset, length);
 		}
 		return null;
 	}
@@ -101,6 +139,24 @@
 		return internalFormatClassBodyDeclarations(source, indentationLevel, lineSeparator, bodyDeclarations, offset, length);
 	}
 
+	private TextEdit formatComment(int kind, String source, int indentationLevel, String lineSeparator, int offset, int length) {
+		final boolean isFormattingComments = DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT));
+		if (isFormattingComments) {
+			if (lineSeparator != null) {
+				this.preferences.line_separator = lineSeparator;
+			} else {
+				this.preferences.line_separator = System.getProperty("line.separator"); //$NON-NLS-1$
+			}
+			this.preferences.initial_indentation_level = indentationLevel;
+			this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, null);
+			final CommentRegion region = createRegion(kind, new Document(source), new Position(offset, length), this.newCodeFormatter);
+			if (region != null) {
+				return this.newCodeFormatter.format(source, region);
+			}
+		}
+		return new MultiTextEdit();
+	}
+
 	private TextEdit formatCompilationUnit(String source, int indentationLevel, String lineSeparator, int offset, int length) {
 		CompilationUnitDeclaration compilationUnitDeclaration = this.codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true);
 		
@@ -245,10 +301,38 @@
 
 		this.newCodeFormatter = new CodeFormatterVisitor(this.preferences, this.options, offset, length, this.codeSnippetParsingUtil);
 		
-		return  this.newCodeFormatter.format(source, constructorDeclaration);
+		return this.newCodeFormatter.format(source, constructorDeclaration);
 	}
 
 	private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, int offset, int length) {
+		if (ProbingScanner == null) {
+			// scanner use to check if the kind could be K_JAVA_DOC, K_MULTI_LINE_COMMENT or K_SINGLE_LINE_COMMENT 
+			ProbingScanner = new Scanner(true, true, false/*nls*/, ClassFileConstants.JDK1_3, ClassFileConstants.JDK1_3, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+		}
+		ProbingScanner.setSource(source.toCharArray());
+		ProbingScanner.resetTo(offset, offset + length);
+		try {
+			switch(ProbingScanner.getNextToken()) {
+				case ITerminalSymbols.TokenNameCOMMENT_BLOCK :
+					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
+						return formatComment(K_MULTI_LINE_COMMENT, source, indentationLevel, lineSeparator, offset, length);
+					}
+					break;
+				case ITerminalSymbols.TokenNameCOMMENT_LINE :
+					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
+						return formatComment(K_SINGLE_LINE_COMMENT, source, indentationLevel, lineSeparator, offset, length);
+					}
+					break;
+				case ITerminalSymbols.TokenNameCOMMENT_JAVADOC :
+					if (ProbingScanner.getCurrentTokenEndPosition() == offset + length - 1) {
+						return formatComment(K_JAVA_DOC, source, indentationLevel, lineSeparator, offset, length);
+					}
+			}
+		} catch (InvalidInputException e) {
+			// ignore
+		}
+		ProbingScanner.setSource((char[]) null);
+
 		Expression expression = this.codeSnippetParsingUtil.parseExpression(source.toCharArray(), getDefaultCompilerOptions(), true);
 		if (expression != null) {
 			return internalFormatExpression(source, indentationLevel, lineSeparator, expression, offset, length);
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index c01a6d6..a62571f 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,12 +23,22 @@
  */
 
 public class DefaultCodeFormatterOptions {
+	public static final int TAB = 1;
+	public static final int SPACE = 2;
+	public static final int MIXED = 4;
+	
 	public static DefaultCodeFormatterOptions getDefaultSettings() {
 		DefaultCodeFormatterOptions options = new DefaultCodeFormatterOptions();
 		options.setDefaultSettings();
 		return options;
 	}
 	
+	public static DefaultCodeFormatterOptions getEclipseDefaultSettings() {
+		DefaultCodeFormatterOptions options = new DefaultCodeFormatterOptions();
+		options.setEclipseDefaultSettings();
+		return options;
+	}
+
 	public static DefaultCodeFormatterOptions getJavaConventionsSettings() {
 		DefaultCodeFormatterOptions options = new DefaultCodeFormatterOptions();
 		options.setJavaConventionsSettings();
@@ -43,6 +53,7 @@
 	public int alignment_for_binary_expression;
 	public int alignment_for_compact_if;
 	public int alignment_for_conditional_expression;
+	public int alignment_for_enum_constants;
 	public int alignment_for_expressions_in_array_initializer;
 	public int alignment_for_multiple_fields;
 	public int alignment_for_parameters_in_constructor_declaration;
@@ -83,6 +94,17 @@
 	public int blank_lines_between_type_declarations;
 	public int blank_lines_at_beginning_of_method_body;
 	
+	public boolean comment_clear_blank_lines;
+	public boolean comment_format;
+	public boolean comment_format_header;
+	public boolean comment_format_html;
+	public boolean comment_format_source;
+	public boolean comment_indent_parameter_description;
+	public boolean comment_indent_root_tags;
+	public boolean comment_insert_empty_line_before_root_tags;
+	public boolean comment_insert_new_line_for_parameter;
+	public int comment_line_length;
+	
 	public boolean indent_statements_compare_to_block;
 	public boolean indent_statements_compare_to_body;
 	public boolean indent_body_declarations_compare_to_enum_constant_header;
@@ -91,7 +113,9 @@
 	public boolean indent_breaks_compare_to_cases;
 	public boolean indent_switchstatements_compare_to_cases;
 	public boolean indent_switchstatements_compare_to_switch;
-	
+	public int indentation_size;
+
+	public boolean insert_new_line_after_annotation;
 	public boolean insert_new_line_after_opening_brace_in_array_initializer;
 	public boolean insert_new_line_at_end_of_file_if_missing;
 	public boolean insert_new_line_before_catch_in_try_statement;
@@ -268,8 +292,9 @@
 	public int tab_size;
 	public final char filling_space = ' ';
 	public int page_width;
-	public boolean use_tab;
-
+	public int tab_char;
+	public boolean use_tabs_only_for_leading_indentations;
+	
 	public int initial_indentation_level;
 	public String line_separator;
 	
@@ -297,6 +322,7 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION, getAlignment(this.alignment_for_binary_expression));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_COMPACT_IF, getAlignment(this.alignment_for_compact_if));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION, getAlignment(this.alignment_for_conditional_expression));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS, getAlignment(this.alignment_for_enum_constants));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER, getAlignment(this.alignment_for_expressions_in_array_initializer));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_MULTIPLE_FIELDS, getAlignment(this.alignment_for_multiple_fields));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_CONSTRUCTOR_DECLARATION, getAlignment(this.alignment_for_parameters_in_constructor_declaration));
@@ -319,6 +345,16 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION, this.brace_position_for_method_declaration);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION, this.brace_position_for_type_declaration);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH, this.brace_position_for_switch);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES, this.comment_clear_blank_lines ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT, this.comment_format ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER, this.comment_format_header ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HTML, this.comment_format_html ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE, this.comment_format_source ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION, this.comment_indent_parameter_description ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_ROOT_TAGS, this.comment_indent_root_tags ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS, this.comment_insert_empty_line_before_root_tags ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER, this.comment_insert_new_line_for_parameter ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH, Integer.toString(this.comment_line_length));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION, Integer.toString(this.continuation_indentation));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER, Integer.toString(this.continuation_indentation_for_array_initializer));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AFTER_IMPORTS, Integer.toString(this.blank_lines_after_imports));
@@ -340,6 +376,8 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_BREAKS_COMPARE_TO_CASES, this.indent_breaks_compare_to_cases ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_CASES, this.indent_switchstatements_compare_to_cases ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH, this.indent_switchstatements_compare_to_switch ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, Integer.toString(this.indentation_size));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION, this.insert_new_line_after_annotation ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER, this.insert_new_line_after_opening_brace_in_array_initializer? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AT_END_OF_FILE_IF_MISSING, this.insert_new_line_at_end_of_file_if_missing ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, this.insert_new_line_before_catch_in_try_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
@@ -514,8 +552,19 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, Integer.toString(this.number_of_empty_lines_to_preserve));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_PUT_EMPTY_STATEMENT_ON_NEW_LINE, this.put_empty_statement_on_new_line ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, Integer.toString(this.page_width));
-		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, this.use_tab ? JavaCore.TAB: JavaCore.SPACE);
+		switch(this.tab_char) {
+			case SPACE :
+				options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
+				break;
+			case TAB :
+				options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.TAB);
+				break;
+			case MIXED :
+				options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, DefaultCodeFormatterConstants.MIXED);
+				break;
+		}
 		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, Integer.toString(this.tab_size));
+		options.put(DefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS, this.use_tabs_only_for_leading_indentations ?  DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		return options;
 	}
 
@@ -600,6 +649,16 @@
 				this.alignment_for_conditional_expression = Alignment.M_ONE_PER_LINE_SPLIT;
 			}
 		}
+		final Object alignmentForEnumConstantsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ENUM_CONSTANTS);
+		if (alignmentForEnumConstantsOption != null) {
+			try {
+				this.alignment_for_enum_constants = Integer.parseInt((String) alignmentForEnumConstantsOption);
+			} catch (NumberFormatException e) {
+				this.alignment_for_enum_constants = Alignment.NONE;
+			} catch (ClassCastException e) {
+				this.alignment_for_enum_constants = Alignment.NONE;
+			}
+		}
 		final Object alignmentForExpressionsInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER);
 		if (alignmentForExpressionsInArrayInitializerOption != null) {
 			try {
@@ -922,6 +981,52 @@
 				this.blank_lines_at_beginning_of_method_body = 0;
 			}
 		}
+		final Object commentClearBlankLinesOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_CLEAR_BLANK_LINES);
+		if (commentClearBlankLinesOption != null) {
+			this.comment_clear_blank_lines = DefaultCodeFormatterConstants.TRUE.equals(commentClearBlankLinesOption);
+		}
+		final Object commentFormatOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT);
+		if (commentFormatOption != null) {
+			this.comment_format = DefaultCodeFormatterConstants.TRUE.equals(commentFormatOption);
+		}
+		final Object commentFormatHeaderOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HEADER);
+		if (commentFormatHeaderOption != null) {
+			this.comment_format_header = DefaultCodeFormatterConstants.TRUE.equals(commentFormatHeaderOption);
+		}
+		final Object commentFormatHtmlOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_HTML);
+		if (commentFormatHtmlOption != null) {
+			this.comment_format_html = DefaultCodeFormatterConstants.TRUE.equals(commentFormatHtmlOption);
+		}
+		final Object commentFormatSourceOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_SOURCE);
+		if (commentFormatSourceOption != null) {
+			this.comment_format_source = DefaultCodeFormatterConstants.TRUE.equals(commentFormatSourceOption);
+		}
+		final Object commentIndentParameterDescriptionOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_PARAMETER_DESCRIPTION);
+		if (commentIndentParameterDescriptionOption != null) {
+			this.comment_indent_parameter_description = DefaultCodeFormatterConstants.TRUE.equals(commentIndentParameterDescriptionOption);
+		}
+		final Object commentIndentRootTagsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INDENT_ROOT_TAGS);
+		if (commentIndentRootTagsOption != null) {
+			this.comment_indent_root_tags = DefaultCodeFormatterConstants.TRUE.equals(commentIndentRootTagsOption);
+		}
+		final Object commentInsertEmptyLineBeforeRootTagsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_EMPTY_LINE_BEFORE_ROOT_TAGS);
+		if (commentInsertEmptyLineBeforeRootTagsOption != null) {
+			this.comment_insert_empty_line_before_root_tags = JavaCore.INSERT.equals(commentInsertEmptyLineBeforeRootTagsOption);
+		}
+		final Object commentInsertNewLineForParameterOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_INSERT_NEW_LINE_FOR_PARAMETER);
+		if (commentInsertNewLineForParameterOption != null) {
+			this.comment_insert_new_line_for_parameter = JavaCore.INSERT.equals(commentInsertNewLineForParameterOption);
+		}
+		final Object commentLineLengthOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_LENGTH);
+		if (commentLineLengthOption != null) {
+			try {
+				this.comment_line_length = Integer.parseInt((String) commentLineLengthOption);
+			} catch (NumberFormatException e) {
+				this.comment_line_length = 80;
+			} catch(ClassCastException e) {
+				this.comment_line_length = 80;
+			}
+		}
 		final Object indentStatementsCompareToBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK);
 		if (indentStatementsCompareToBlockOption != null) {
 			this.indent_statements_compare_to_block = DefaultCodeFormatterConstants.TRUE.equals(indentStatementsCompareToBlockOption);
@@ -954,6 +1059,20 @@
 		if (indentSwitchstatementsCompareToSwitchOption != null) {
 			this.indent_switchstatements_compare_to_switch = DefaultCodeFormatterConstants.TRUE.equals(indentSwitchstatementsCompareToSwitchOption);
 		}
+		final Object indentationSizeOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE);
+		if (indentationSizeOption != null) {
+			try {
+				this.indentation_size = Integer.parseInt((String) indentationSizeOption);
+			} catch (NumberFormatException e) {
+				this.indentation_size = 4;
+			} catch(ClassCastException e) {
+				this.indentation_size = 4;
+			}
+		}
+		final Object insertNewLineAfterAnnotationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION);
+		if (insertNewLineAfterAnnotationOption != null) {
+			this.insert_new_line_after_annotation = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOption);
+		}
 		final Object insertNewLineAfterOpeningBraceInArrayInitializerOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER);
 		if (insertNewLineAfterOpeningBraceInArrayInitializerOption != null) {
 			this.insert_new_line_after_opening_brace_in_array_initializer = JavaCore.INSERT.equals(insertNewLineAfterOpeningBraceInArrayInitializerOption);
@@ -1662,6 +1781,10 @@
 				this.tab_size = 4;
 			}
 		}
+		final Object useTabsOnlyForLeadingIndentationsOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_USE_TABS_ONLY_FOR_LEADING_INDENTATIONS);
+		if (useTabsOnlyForLeadingIndentationsOption != null) {
+			this.use_tabs_only_for_leading_indentations = DefaultCodeFormatterConstants.TRUE.equals(useTabsOnlyForLeadingIndentationsOption);
+		}
 		final Object pageWidthOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT);
 		if (pageWidthOption != null) {
 			try {
@@ -1674,7 +1797,13 @@
 		}
 		final Object useTabOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
 		if (useTabOption != null) {
-			this.use_tab = JavaCore.TAB.equals(useTabOption);
+			if (JavaCore.TAB.equals(useTabOption)) {
+				this.tab_char = TAB;
+			} else if (JavaCore.SPACE.equals(useTabOption)) {
+				this.tab_char = SPACE;
+			} else {
+				this.tab_char = MIXED;
+			}
 		}
 	}
 
@@ -1687,6 +1816,7 @@
 		this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_compact_if = Alignment.M_ONE_PER_LINE_SPLIT | Alignment.M_INDENT_BY_ONE;
 		this.alignment_for_conditional_expression = Alignment.M_ONE_PER_LINE_SPLIT;
+		this.alignment_for_enum_constants = Alignment.NONE;
 		this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_multiple_fields = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_parameters_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
@@ -1709,6 +1839,16 @@
 		this.brace_position_for_method_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
 		this.brace_position_for_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
 		this.brace_position_for_switch = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.comment_clear_blank_lines = false;
+		this.comment_format = true;
+		this.comment_format_header = false;
+		this.comment_format_html = true;
+		this.comment_format_source = true;
+		this.comment_indent_parameter_description = true;
+		this.comment_indent_root_tags = true;
+		this.comment_insert_empty_line_before_root_tags = true;
+		this.comment_insert_new_line_for_parameter = true;
+		this.comment_line_length = 80;
 		this.continuation_indentation = 2;
 		this.continuation_indentation_for_array_initializer = 2;
 		this.blank_lines_after_imports = 0;
@@ -1730,6 +1870,8 @@
 		this.indent_breaks_compare_to_cases = true;
 		this.indent_switchstatements_compare_to_cases = true;
 		this.indent_switchstatements_compare_to_switch = true;
+		this.indentation_size = 4;
+		this.insert_new_line_after_annotation = true;
 		this.insert_new_line_after_opening_brace_in_array_initializer = false;
 		this.insert_new_line_at_end_of_file_if_missing = false;
 		this.insert_new_line_before_catch_in_try_statement = false;
@@ -1904,9 +2046,16 @@
 		this.put_empty_statement_on_new_line = false;
 		this.tab_size = 4;
 		this.page_width = 80;
-		this.use_tab = true; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49081
+		this.tab_char = TAB; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49081
+		this.use_tabs_only_for_leading_indentations = false;
 	}
 	
+	public void setEclipseDefaultSettings() {
+		setJavaConventionsSettings();
+		this.tab_char = TAB;
+		this.tab_size = 4;
+	}
+
 	public void setJavaConventionsSettings() {
 		this.alignment_for_arguments_in_allocation_expression = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_arguments_in_enum_constant = Alignment.M_COMPACT_SPLIT;
@@ -1916,6 +2065,7 @@
 		this.alignment_for_binary_expression = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_compact_if = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_conditional_expression = Alignment.M_NEXT_PER_LINE_SPLIT;
+		this.alignment_for_enum_constants = Alignment.NONE;
 		this.alignment_for_expressions_in_array_initializer = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_multiple_fields = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_parameters_in_constructor_declaration = Alignment.M_COMPACT_SPLIT;
@@ -1938,6 +2088,16 @@
 		this.brace_position_for_method_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
 		this.brace_position_for_type_declaration = DefaultCodeFormatterConstants.END_OF_LINE;
 		this.brace_position_for_switch = DefaultCodeFormatterConstants.END_OF_LINE;
+		this.comment_clear_blank_lines = false;
+		this.comment_format = true;
+		this.comment_format_header = false;
+		this.comment_format_html = true;
+		this.comment_format_source = true;
+		this.comment_indent_parameter_description = true;
+		this.comment_indent_root_tags = true;
+		this.comment_insert_empty_line_before_root_tags = true;
+		this.comment_insert_new_line_for_parameter = true;
+		this.comment_line_length = 80;
 		this.continuation_indentation = 2;
 		this.continuation_indentation_for_array_initializer = 2;
 		this.blank_lines_after_imports = 1;
@@ -1959,6 +2119,8 @@
 		this.indent_breaks_compare_to_cases = true;
 		this.indent_switchstatements_compare_to_cases = true;
 		this.indent_switchstatements_compare_to_switch = false;
+		this.indentation_size = 4;
+		this.insert_new_line_after_annotation = true;
 		this.insert_new_line_after_opening_brace_in_array_initializer = false;
 		this.insert_new_line_at_end_of_file_if_missing = false;
 		this.insert_new_line_before_catch_in_try_statement = false;
@@ -2133,6 +2295,7 @@
 		this.put_empty_statement_on_new_line = true;
 		this.tab_size = 4;
 		this.page_width = 80;
-		this.use_tab = false;
+		this.tab_char = SPACE;
+		this.use_tabs_only_for_leading_indentations = false;
 	}
 }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java
index ef192a3..94f877f 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Location.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 /**
@@ -25,6 +25,7 @@
 	public boolean pendingSpace;
 	public int nlsTagCounter;
 	public int lastLocalDeclarationSourceStart;
+	public int numberOfIndentations;
 
 	// chunk management
 	public int lastNumberOfNewLines;
@@ -47,6 +48,7 @@
 		this.pendingSpace = scribe.pendingSpace;
 		this.editsIndex = scribe.editsIndex;
 		this.nlsTagCounter = scribe.nlsTagCounter;
+		this.numberOfIndentations = scribe.numberOfIndentations;
 		textEdit = scribe.getLastEdit();
 	}
 }
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java
index 4211e86..849af05 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OptimizedReplaceEdit.java
@@ -1,22 +1,22 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
-class OptimizedReplaceEdit {
+public class OptimizedReplaceEdit {
 	
 	int offset;
 	int length;
 	String replacement;
 	
-	OptimizedReplaceEdit(int offset, int length, String replacement) {
+	public OptimizedReplaceEdit(int offset, int length, String replacement) {
 		this.offset = offset;
 		this.length = length;
 		this.replacement = replacement;
@@ -25,4 +25,4 @@
 	public String toString() {
 		return "(" + this.offset + ", length " + this.length + " :>" + this.replacement + "<"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
index 8fc3e41..a42e291 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/Scribe.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2002, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
 import java.util.Arrays;
@@ -39,6 +39,7 @@
 	private static final int INITIAL_SIZE = 100;
 	
 	private boolean checkLineWrapping;
+	/** one-based column */
 	public int column;
 	private int[][] commentPositions;
 		
@@ -50,8 +51,6 @@
 	private OptimizedReplaceEdit[] edits;
 	public int editsIndex;
 	
-	// TODO (olivier) to remove when the testing is done
-	private char fillingSpace;
 	public CodeFormatterVisitor formatter;
 	public int indentationLevel;	
 	public int lastNumberOfNewLines;
@@ -68,10 +67,13 @@
 
 	public Scanner scanner;
 	public int scannerEndPosition;
-	public int tabSize;	
+	public int tabLength;	
+	public int indentationSize;	
 	private int textRegionEnd;
 	private int textRegionStart;
-	public boolean useTab;
+	public int tabChar;
+	public int numberOfIndentations;
+	private boolean useTabsOnlyForLeadingIndents;
 
 	Scribe(CodeFormatterVisitor formatter, Map settings, int offset, int length, CodeSnippetParsingUtil codeSnippetParsingUtil) {
 		if (settings != null) {
@@ -88,10 +90,18 @@
 		}
 		this.formatter = formatter;
 		this.pageWidth = formatter.preferences.page_width;
-		this.tabSize = formatter.preferences.tab_size;
-		this.useTab = formatter.preferences.use_tab;
-		this.fillingSpace = formatter.preferences.filling_space;
-		setLineSeparatorAndIdentationLevel(formatter.preferences);
+		this.tabLength = formatter.preferences.tab_size;
+		this.indentationLevel= 0; // initialize properly
+		this.numberOfIndentations = 0;
+		this.useTabsOnlyForLeadingIndents = formatter.preferences.use_tabs_only_for_leading_indentations;
+		this.tabChar = formatter.preferences.tab_char;
+		if (this.tabChar == DefaultCodeFormatterOptions.MIXED) {
+			this.indentationSize = formatter.preferences.indentation_size;
+		} else {
+			this.indentationSize = this.tabLength;
+		}
+		this.lineSeparator = formatter.preferences.line_separator;
+		this.indentationLevel = formatter.preferences.initial_indentation_level * this.indentationSize;
 		this.textRegionStart = offset;
 		this.textRegionEnd = offset + length - 1;
 		if (codeSnippetParsingUtil != null) {
@@ -112,7 +122,7 @@
 		addOptimizedReplaceEdit(start, end - start + 1, EMPTY_STRING); //$NON-NLS-1$
 	}
 
-	private final void addInsertEdit(int insertPosition, String insertedString) {
+	public final void addInsertEdit(int insertPosition, String insertedString) {
 		if (this.edits.length == this.editsIndex) {
 			// resize
 			resize();
@@ -181,7 +191,7 @@
 		}
 	}
 	
-	private final void addReplaceEdit(int start, int end, String replacement) {
+	public final void addReplaceEdit(int start, int end, String replacement) {
 		if (this.edits.length == this.editsIndex) {
 			// resize
 			resize();
@@ -234,7 +244,7 @@
 				current = current.enclosing;
 			}
 			if ((current.mode & Alignment.M_MULTICOLUMN) != 0) {
-				final int indentSize = this.useTab ? 1 : this.tabSize;
+				final int indentSize = this.indentationSize;
 				switch(current.chunkKind) {
 					case Alignment.CHUNK_METHOD :
 					case Alignment.CHUNK_TYPE :
@@ -261,7 +271,7 @@
 					case Alignment.M_NEXT_PER_LINE_SPLIT :
 					case Alignment.M_NEXT_SHIFTED_SPLIT :
 					case Alignment.M_ONE_PER_LINE_SPLIT :
-						final int indentSize = this.useTab ? 1 : this.tabSize;
+						final int indentSize = this.indentationSize;
 						switch(current.chunkKind) {
 							case Alignment.CHUNK_METHOD :
 							case Alignment.CHUNK_TYPE :
@@ -316,6 +326,7 @@
 			throw new AbortFormatting("could not find matching alignment: "+alignment); //$NON-NLS-1$
 		}
 		this.indentationLevel = alignment.location.outputIndentationLevel;
+		this.numberOfIndentations = alignment.location.numberOfIndentations;
 		this.formatter.lastLocalDeclarationSourceStart = alignment.location.lastLocalDeclarationSourceStart;	
 		if (discardAlignment){ 
 			this.currentAlignment = alignment.enclosing;
@@ -332,6 +343,7 @@
 			throw new AbortFormatting("could not find matching alignment: "+alignment); //$NON-NLS-1$
 		}
 		this.indentationLevel = current.location.outputIndentationLevel;
+		this.numberOfIndentations = current.location.numberOfIndentations;
 		this.formatter.lastLocalDeclarationSourceStart = alignment.location.lastLocalDeclarationSourceStart;	
 		this.memberAlignment = current.enclosing;
 	}
@@ -348,11 +360,7 @@
 	 * @return int
 	 */
 	public int getColumnIndentationLevel() {
-		if (this.useTab) {
-			return (this.column - 1)/ this.tabSize; 
-		} else {
-			return this.column - 1;
-		}
+		return this.column - 1;
 	}	
 	
 	public final int getCommentIndex(int position) {
@@ -395,6 +403,7 @@
 			line += linesNumber;
 			column = 1;
 			needSpace = false;
+			this.pendingSpace = false;
 		} else if (lastNumberOfNewLines == 1) {
 			for (int i = 0; i < linesNumber; i++) {
 				buffer.append(this.lineSeparator);
@@ -403,6 +412,7 @@
 			line += linesNumber;
 			column = 1;
 			needSpace = false;
+			this.pendingSpace = false;
 		} else {
 			if ((lastNumberOfNewLines - 1) >= linesNumber) {
 				// there is no need to add new lines
@@ -416,21 +426,10 @@
 			line += realNewLineNumber;
 			column = 1;
 			needSpace = false;
+			this.pendingSpace = false;
 		}
 		return String.valueOf(buffer);
 	}
-	/** 
-	 * Answer indentation level based on column estimated position
-	 * (if column is not indented, then use indentationLevel)
-	 */
-	public int getIndentationLevel(int someColumn) {
-		if (someColumn == 1) return this.indentationLevel;
-		if (this.useTab) {
-			return (someColumn - 1) / this.tabSize;
-		} else {
-			return someColumn - 1;
-		}
-	}	
 
 	public OptimizedReplaceEdit getLastEdit() {
 		if (this.editsIndex > 0) {
@@ -465,6 +464,7 @@
 		lastNumberOfNewLines = 1;
 		column = 1;
 		needSpace = false;
+		this.pendingSpace = false;
 		return this.lineSeparator;
 	}
 
@@ -473,14 +473,20 @@
 	 * (if column is not indented, then use indentationLevel)
 	 */
 	public int getNextIndentationLevel(int someColumn) {
-		if (someColumn == 1) return this.indentationLevel;
-		if (this.useTab) {
-			int rem = (someColumn - 1)% this.tabSize; // round to superior
-			return rem == 0 ? (someColumn - 1)/ this.tabSize : ((someColumn - 1)/ this.tabSize)+1;
+		int indent = someColumn - 1;
+		if (indent == 0)
+			return this.indentationLevel;
+		if (this.tabChar == DefaultCodeFormatterOptions.TAB) {
+			if (this.useTabsOnlyForLeadingIndents) {
+				return indent;
+			}
+			int rem = indent % this.indentationSize;
+			int addition = rem == 0 ? 0 : this.indentationSize - rem; // round to superior
+			return indent + addition;
 		} else {
-			return someColumn - 1;
+			return indent;
 		}
-	}	
+	}
 
 	private String getPreserveEmptyLines(int count) {
 		if (count > 0) {
@@ -549,6 +555,7 @@
 	 */
 	private boolean hasNLSTag(int sourceStart) {
 		// search the last comment where commentEnd < current lineEnd
+		if (this.lineEnds == null) return false;
 		int index = Arrays.binarySearch(this.lineEnds, sourceStart);
 		int currentLineEnd = this.getLineEnd(-index);
 		if (currentLineEnd != -1) {
@@ -572,11 +579,8 @@
 	}
 	
 	public void indent() {
-		if (this.useTab) {
-			this.indentationLevel++; 
-		} else {
-			this.indentationLevel += tabSize; 
-		}
+		this.indentationLevel += this.indentationSize;
+		this.numberOfIndentations++;
 	}	
 
 	private int indexOf(char[] toBeFound, char[] source, int start, int end) {
@@ -682,8 +686,8 @@
 		this.needSpace = false;		
 		column += s.length;
 		needSpace = true;
-			
 	}
+
 	private void printBlockComment(char[] s, boolean isJavadoc) {
 		int currentTokenStartPosition = this.scanner.getCurrentTokenStartPosition();
 		int currentTokenEndPosition = this.scanner.getCurrentTokenEndPosition() + 1;
@@ -737,7 +741,7 @@
 						StringBuffer buffer = new StringBuffer();
 						buffer.append(this.lineSeparator);
 						printIndentationIfNecessary(buffer);
-						buffer.append(this.fillingSpace);
+						buffer.append(' ');
 				
 						addReplaceEdit(start, previousStart - 1, String.valueOf(buffer));
 					} else {
@@ -1017,6 +1021,7 @@
 		line++; 
 		column = 1;
 		needSpace = false;
+		this.pendingSpace = false;
 		lastNumberOfNewLines = 1;
 		// realign to the proper value
 		if (this.currentAlignment != null) {
@@ -1051,6 +1056,7 @@
 			line += linesNumber;
 			column = 1;
 			needSpace = false;
+			this.pendingSpace = false;
 		} else if (lastNumberOfNewLines == 1) {
 			for (int i = 0; i < linesNumber; i++) {
 				buffer.append(this.lineSeparator);
@@ -1059,6 +1065,7 @@
 			line += linesNumber;
 			column = 1;
 			needSpace = false;
+			this.pendingSpace = false;
 		} else {
 			if ((lastNumberOfNewLines - 1) >= linesNumber) {
 				// there is no need to add new lines
@@ -1072,41 +1079,106 @@
 			line += realNewLineNumber;
 			column = 1;
 			needSpace = false;
+			this.pendingSpace = false;
 		}
 		addInsertEdit(insertPosition, buffer.toString());
 	}
 
 	private void printIndentationIfNecessary() {
-		int indentationColumn = (this.useTab ? this.indentationLevel * this.tabSize : this.indentationLevel)+1;
-		if (this.column < indentationColumn) {
-			StringBuffer buffer = new StringBuffer();
-			for (int i = getColumnIndentationLevel(), max = this.indentationLevel; i < max; i++) { 
-				if (this.useTab) {
-					this.tab(buffer);
-				} else {
-					this.column++;
-					buffer.append(this.fillingSpace);
-					this.needSpace = false;
-				}
-			}
+		StringBuffer buffer = new StringBuffer();
+		printIndentationIfNecessary(buffer);
+		if (buffer.length() > 0) {
 			addInsertEdit(this.scanner.getCurrentTokenStartPosition(), buffer.toString());
 			this.pendingSpace = false;
 		}
 	}
 
-
 	private void printIndentationIfNecessary(StringBuffer buffer) {
-		int indentationColumn = (this.useTab ? this.indentationLevel * this.tabSize : this.indentationLevel)+1;
-		if (this.column < indentationColumn) {
-			for (int i = getColumnIndentationLevel(), max = this.indentationLevel; i < max; i++) { 
-				if (this.useTab) {
-					this.tab(buffer);
+		switch(this.tabChar) {
+			case DefaultCodeFormatterOptions.TAB :
+				boolean useTabsForLeadingIndents = this.useTabsOnlyForLeadingIndents;
+				int numberOfLeadingIndents = this.numberOfIndentations;
+				int indentationsAsTab = 0;
+				if (useTabsForLeadingIndents) {
+					while (this.column <= this.indentationLevel) {
+						if (indentationsAsTab < numberOfLeadingIndents) {
+							buffer.append('\t');
+							indentationsAsTab++;
+							this.lastNumberOfNewLines = 0;
+							int complement = this.tabLength - ((this.column - 1) % this.tabLength); // amount of space
+							this.column += complement;
+							this.needSpace = false;
+						} else {
+							buffer.append(' ');
+							this.column++;
+							this.needSpace = false;
+						}
+					}
 				} else {
+					while (this.column <= this.indentationLevel) {
+						buffer.append('\t');
+						this.lastNumberOfNewLines = 0;
+						int complement = this.tabLength - ((this.column - 1) % this.tabLength); // amount of space
+						this.column += complement;
+						this.needSpace = false;
+					}
+				}
+				break;
+			case DefaultCodeFormatterOptions.SPACE :
+				while (this.column <= this.indentationLevel) {
+					buffer.append(' ');
 					this.column++;
-					buffer.append(this.fillingSpace);
 					this.needSpace = false;
 				}
-			}
+				break;
+			case DefaultCodeFormatterOptions.MIXED :
+				useTabsForLeadingIndents = this.useTabsOnlyForLeadingIndents;
+				numberOfLeadingIndents = this.numberOfIndentations;
+				indentationsAsTab = 0;
+				if (useTabsForLeadingIndents) {
+					final int columnForLeadingIndents = numberOfLeadingIndents * this.indentationSize;
+					while (this.column <= this.indentationLevel) {
+						if (this.column <= columnForLeadingIndents) {
+							if ((this.column - 1 + this.tabLength) <= this.indentationLevel) {
+								buffer.append('\t');
+								this.column += this.tabLength;
+							} else if ((this.column - 1 + this.indentationSize) <= this.indentationLevel) {
+								// print one indentation
+								for (int i = 0, max = this.indentationSize; i < max; i++) {
+									buffer.append(' ');
+									this.column++;
+								}
+							} else {
+								buffer.append(' ');
+								this.column++;
+							}
+						} else {
+							for (int i = this.column, max = this.indentationLevel; i <= max; i++) {
+								buffer.append(' ');
+								this.column++;
+							}
+						}
+						this.needSpace = false;
+					}
+				} else {
+					while (this.column <= this.indentationLevel) {
+						if ((this.column - 1 + this.tabLength) <= this.indentationLevel) {
+							buffer.append('\t');
+							this.column += this.tabLength;
+						} else if ((this.column - 1 + this.indentationSize) <= this.indentationLevel) {
+							// print one indentation
+							for (int i = 0, max = this.indentationSize; i < max; i++) {
+								buffer.append(' ');
+								this.column++;
+							}
+						} else {
+							buffer.append(' ');
+							this.column++;
+						}
+						this.needSpace = false;
+					}
+				}
+				break;
 		}
 	}
 
@@ -1117,6 +1189,7 @@
 			boolean isFirstModifier = true;
 			int currentTokenStartPosition = this.scanner.currentPosition;
 			boolean hasComment = false;
+			boolean hasModifiers = false;
 			while ((this.currentToken = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
 				switch(this.currentToken) {
 					case TerminalTokens.TokenNamepublic :
@@ -1130,17 +1203,22 @@
 					case TerminalTokens.TokenNametransient :
 					case TerminalTokens.TokenNamevolatile :
 					case TerminalTokens.TokenNamestrictfp :
+						hasModifiers = true;
 						this.print(this.scanner.getRawTokenSource(), !isFirstModifier);
 						isFirstModifier = false;
 						currentTokenStartPosition = this.scanner.getCurrentTokenStartPosition();
 						break;
 					case TerminalTokens.TokenNameAT :
+						hasModifiers = true;
 						if (!isFirstModifier) {
 							this.space();
 						}
 						this.scanner.resetTo(this.scanner.getCurrentTokenStartPosition(), this.scannerEndPosition - 1);
 						if (annotationsIndex < annotationsLength) {
 							annotations[annotationsIndex++].traverse(visitor, (BlockScope) null);
+							if (this.formatter.preferences.insert_new_line_after_annotation) {
+								this.printNewLine();
+							}
 						} else {
 							return;
 						}
@@ -1186,6 +1264,9 @@
 						hasComment = false;
 						break;
 					default:
+						if (hasModifiers) {
+							this.space();
+						}
 						// step back one token
 						this.scanner.resetTo(currentTokenStartPosition, this.scannerEndPosition - 1);
 						return;					
@@ -1209,6 +1290,7 @@
 		lastNumberOfNewLines = 1;
 		column = 1;
 		needSpace = false;
+		this.pendingSpace = false;
 	}
 
 	public void printNewLine(int insertPosition) {
@@ -1224,6 +1306,7 @@
 		lastNumberOfNewLines = 1;
 		column = 1;
 		needSpace = false;
+		this.pendingSpace = false;
 	}
 
 	public void printNextToken(int expectedTokenType){
@@ -1307,7 +1390,7 @@
 
 	private void printRule(StringBuffer stringBuffer) {
 		for (int i = 0; i < this.pageWidth; i++){
-			if ((i % this.tabSize) == 0) { 
+			if ((i % this.tabLength) == 0) { 
 				stringBuffer.append('+');
 			} else {
 				stringBuffer.append('-');
@@ -1315,7 +1398,7 @@
 		}
 		stringBuffer.append(this.lineSeparator);
 		
-		for (int i = 0; i < (pageWidth / tabSize); i++) {
+		for (int i = 0; i < (pageWidth / tabLength); i++) {
 			stringBuffer.append(i);
 			stringBuffer.append('\t');
 		}			
@@ -1430,6 +1513,7 @@
 		this.line = location.outputLine;
 		this.column = location.outputColumn;
 		this.indentationLevel = location.outputIndentationLevel;
+		this.numberOfIndentations = location.numberOfIndentations;
 		this.lastNumberOfNewLines = location.lastNumberOfNewLines;
 		this.needSpace = location.needSpace;
 		this.pendingSpace = location.pendingSpace;
@@ -1445,15 +1529,6 @@
 		System.arraycopy(this.edits, 0, (this.edits = new OptimizedReplaceEdit[this.editsIndex * 2]), 0, this.editsIndex);
 	}
 
-	public void setLineSeparatorAndIdentationLevel(DefaultCodeFormatterOptions preferences) {
-		this.lineSeparator = preferences.line_separator;
-		if (this.useTab) {
-			this.indentationLevel = preferences.initial_indentation_level;
-		} else {
-			this.indentationLevel = preferences.initial_indentation_level * this.tabSize;
-		}
-	}
-	
 	public void space() {
 		if (!this.needSpace) return;
 		this.lastNumberOfNewLines = 0;
@@ -1462,24 +1537,22 @@
 		this.needSpace = false;		
 	}
 
-	private void tab(StringBuffer buffer) {
-		this.lastNumberOfNewLines = 0;
-		int complement = this.tabSize - ((this.column - 1)% this.tabSize); // amount of space
-		if (this.useTab) {
-			buffer.append('\t');
-		} else {
-			for (int i = 0; i < complement; i++) {
-				buffer.append(this.fillingSpace);
-			}
-		}
-		this.column += complement;
-		this.needSpace = false;
-	}
-	
 	public String toString() {
 		StringBuffer stringBuffer = new StringBuffer();
 		stringBuffer
-			.append("(page witdh = " + this.pageWidth + ") - (useTab = " + this.useTab + ") - (tabSize = " + this.tabSize + ")")	//$NON-NLS-1$	//$NON-NLS-2$	//$NON-NLS-3$	//$NON-NLS-4$
+			.append("(page width = " + this.pageWidth + ") - (tabChar = ");//$NON-NLS-1$//$NON-NLS-2$
+		switch(this.tabChar) {
+			case DefaultCodeFormatterOptions.TAB :
+				 stringBuffer.append("TAB");//$NON-NLS-1$
+				 break;
+			case DefaultCodeFormatterOptions.SPACE :
+				 stringBuffer.append("SPACE");//$NON-NLS-1$
+				 break;
+			default :
+				 stringBuffer.append("MIXED");//$NON-NLS-1$
+		}
+		stringBuffer
+			.append(") - (tabSize = " + this.tabLength + ")")//$NON-NLS-1$//$NON-NLS-2$
 			.append(this.lineSeparator)
 			.append("(line = " + this.line + ") - (column = " + this.column + ") - (identationLevel = " + this.indentationLevel + ")")	//$NON-NLS-1$	//$NON-NLS-2$	//$NON-NLS-3$	//$NON-NLS-4$
 			.append(this.lineSeparator)
@@ -1492,10 +1565,7 @@
 	}
 	
 	public void unIndent() {
-		if (this.useTab) {
-			this.indentationLevel--;
-		} else {
-			this.indentationLevel -= tabSize;
-		}
+		this.indentationLevel -= this.indentationSize;
+		this.numberOfIndentations--;
 	}
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java
index a43ceb9..0af759f 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/Alignment.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter.align;
 
 import org.eclipse.jdt.internal.formatter.Location;
@@ -144,10 +144,10 @@
 		this.wasSplit = false;
 		
 		// initialize the break indentation level, using modes and continuationIndentationLevel preference
-		final int indentSize = this.scribe.useTab ? 1 : this.scribe.tabSize;
+		final int indentSize = this.scribe.indentationSize;
 		int currentColumn = this.location.outputColumn;
 		if (currentColumn == 1) {
-		    currentColumn = this.location.outputIndentationLevel * indentSize + 1;
+		    currentColumn = this.location.outputIndentationLevel + 1;
 		}
 		
 		if ((mode & M_INDENT_ON_COLUMN) != 0) {
@@ -160,7 +160,6 @@
 			// indent broken fragments exactly one level deeper than current indentation
 			this.breakIndentationLevel = this.location.outputIndentationLevel + indentSize;
 		} else {
-			// indent broken fragments by one continuation indentation deeper than current indentation
 			this.breakIndentationLevel = this.location.outputIndentationLevel + continuationIndent * indentSize;
 		}
 		this.shiftBreakIndentationLevel = this.breakIndentationLevel + indentSize;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java
index 27759b5..827b071 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/align/AlignmentException.java
@@ -1,13 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0 
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
 package org.eclipse.jdt.internal.formatter.align;
 
 /**
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentFormatterUtil.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentFormatterUtil.java
new file mode 100644
index 0000000..eed01e3
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentFormatterUtil.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.Map;
+
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.BadPositionCategoryException;
+import org.eclipse.jface.text.DefaultPositionUpdater;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.Position;
+
+import org.eclipse.jdt.core.ToolFactory;
+
+import org.eclipse.jdt.internal.core.Assert;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Comment formatting utils.
+ * 
+ * @since 3.1
+ */
+public class CommentFormatterUtil {
+
+	/**
+	 * Evaluates the edit on the given string.
+	 * 
+	 * @throws IllegalArgumentException if the positions are not inside the
+	 *                 string
+	 */
+	public static String evaluateFormatterEdit(String string, TextEdit edit, Position[] positions) {
+		try {
+			Document doc= createDocument(string, positions);
+			edit.apply(doc, 0);
+			if (positions != null) {
+				for (int i= 0; i < positions.length; i++) {
+					Assert.isTrue(!positions[i].isDeleted, "Position got deleted"); //$NON-NLS-1$
+				}
+			}
+			return doc.get();
+		} catch (BadLocationException e) {
+			log(e); // bug in the formatter
+			Assert.isTrue(false, "Formatter created edits with wrong positions: " + e.getMessage()); //$NON-NLS-1$
+		}
+		return null;
+	}
+	
+	/**
+	 * Creates edits that describe how to format the given string. Returns
+	 * <code>null</code> if the code could not be formatted for the given
+	 * kind.
+	 * 
+	 * @throws IllegalArgumentException if the offset and length are not
+	 *                 inside the string
+	 */
+	public static TextEdit format2(int kind, String string, int indentationLevel, String lineSeparator, Map options) {
+		int length= string.length();
+		if (0 < 0 || length < 0 || 0 + length > string.length()) {
+			throw new IllegalArgumentException("offset or length outside of string. offset: " + 0 + ", length: " + length + ", string size: " + string.length());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+		}
+		return ToolFactory.createCodeFormatter(options).format(kind, string, 0, length, indentationLevel, lineSeparator);
+	}
+
+	/**
+	 * Returns a document with the given content and the given positions
+	 * registered with the {@link DefaultPositionUpdater}.
+	 * 
+	 * @param content the content
+	 * @param positions the positions
+	 * @return the document
+	 * @throws IllegalArgumentException
+	 */
+	private static Document createDocument(String content, Position[] positions) throws IllegalArgumentException {
+		Document doc= new Document(content);
+		try {
+			if (positions != null) {
+				final String POS_CATEGORY= "myCategory"; //$NON-NLS-1$
+				
+				doc.addPositionCategory(POS_CATEGORY);
+				doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
+					protected boolean notDeleted() {
+						if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
+							fPosition.offset= fOffset + fLength; // deleted positions: set to end of remove
+							return false;
+						}
+						return true;
+					}
+				});
+				for (int i= 0; i < positions.length; i++) {
+					try {
+						doc.addPosition(POS_CATEGORY, positions[i]);
+					} catch (BadLocationException e) {
+						throw new IllegalArgumentException("Position outside of string. offset: " + positions[i].offset + ", length: " + positions[i].length + ", string size: " + content.length());   //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+					}
+				}
+			}
+		} catch (BadPositionCategoryException cannotHappen) {
+			// can not happen: category is correctly set up
+		}
+		return doc;
+	}
+
+	/**
+	 * Logs the given throwable.
+	 * 
+	 * @param t the throwable
+	 * @since 3.1
+	 */
+	public static void log(Throwable t) {
+		Util.log(t, "Exception occured while formatting comments"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentLine.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentLine.java
new file mode 100644
index 0000000..1abb546
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentLine.java
@@ -0,0 +1,304 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.LinkedList;
+
+/**
+ * General comment line in a comment region.
+ * 
+ * @since 3.0
+ */
+public abstract class CommentLine implements IBorderAttributes {
+
+	/** Prefix of non-formattable comment lines */
+	protected static final String NON_FORMAT_START_PREFIX= "/*-"; //$NON-NLS-1$
+
+	/** The attributes of this line */
+	private int fAttributes= 0;
+
+	/** The parent region of this line */
+	private final CommentRegion fParent;
+
+	/** The comment ranges in this line */
+	private final LinkedList fRanges= new LinkedList();
+
+	/**
+	 * Creates a new comment line.
+	 * 
+	 * @param parent comment region to create the comment line for
+	 */
+	protected CommentLine(final CommentRegion parent) {
+		fParent= parent;
+	}
+
+	/**
+	 * Adapts the line attributes from the previous line in the comment
+	 * region.
+	 * 
+	 * @param previous the previous comment line in the comment region
+	 */
+	protected abstract void adapt(final CommentLine previous);
+
+	/**
+	 * Appends the specified comment range to this comment line.
+	 * 
+	 * @param range comment range to append to this line
+	 */
+	protected void append(final CommentRange range) {
+		fRanges.add(range);
+	}
+
+	/**
+	 * Formats this comment line as content line.
+	 * 
+	 * @param predecessor the predecessor comment line in the comment region
+	 * @param last the most recently processed comment range
+	 * @param indentation the indentation of the comment region
+	 * @param line the index of this comment line in the comment region
+	 * @return the first comment range in this comment line
+	 */
+	protected CommentRange formatLine(final CommentLine predecessor, final CommentRange last, final String indentation, final int line) {
+
+		int offset= 0;
+		int length= 0;
+
+		CommentRange next= last;
+		CommentRange previous= null;
+
+		final int stop= fRanges.size() - 1;
+		final int end= fParent.getSize() - 1;
+
+		for (int index= stop; index >= 0; index--) {
+
+			previous= next;
+			next= (CommentRange)fRanges.get(index);
+
+			if (fParent.canFormat(previous, next)) {
+
+				offset= next.getOffset() + next.getLength();
+				length= previous.getOffset() - offset;
+
+				if (index == stop && line != end)
+					fParent.logEdit(fParent.getDelimiter(predecessor, this, previous, next, indentation), offset, length);
+				else
+					fParent.logEdit(fParent.getDelimiter(previous, next), offset, length);
+			}
+		}
+		return next;
+	}
+
+	/**
+	 * Formats this comment line as end line having a lower border
+	 * consisting of content line prefixes.
+	 * 
+	 * @param range last comment range of the last comment line in the
+	 *                comment region
+	 * @param indentation the indentation of the comment region
+	 * @param length the maximal length of text in this comment region
+	 *                measured in average character widths
+	 */
+	protected void formatLowerBorder(final CommentRange range, final String indentation, final int length) {
+
+		final int offset= range.getOffset() + range.getLength();
+
+		final StringBuffer buffer= new StringBuffer(length);
+		final String end= getEndingPrefix();
+		final String delimiter= fParent.getDelimiter();
+
+		if (fParent.isSingleLine() && fParent.getSize() == 1)
+			buffer.append(end);
+		else {
+
+			final String filler= getContentPrefix().trim();
+
+			buffer.append(delimiter);
+			buffer.append(indentation);
+
+			if (fParent.hasBorder(BORDER_LOWER)) {
+
+				buffer.append(' ');
+				for (int character= 0; character < length; character++)
+					buffer.append(filler);
+
+				buffer.append(end.trim());
+
+			} else
+				buffer.append(end);
+		}
+		fParent.logEdit(buffer.toString(), offset, fParent.getLength() - offset);
+	}
+
+	/**
+	 * Formats this comment line as start line having an upper border
+	 * consisting of content line prefixes.
+	 * 
+	 * @param range the first comment range in the comment region
+	 * @param indentation the indentation of the comment region
+	 * @param length the maximal length of text in this comment region
+	 *                measured in average character widths
+	 */
+	protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) {
+
+		final StringBuffer buffer= new StringBuffer(length);
+		final String start= getStartingPrefix();
+		final String content= getContentPrefix();
+
+		if (fParent.isSingleLine() && fParent.getSize() == 1)
+			buffer.append(start);
+		else {
+
+			final String trimmed= start.trim();
+			final String filler= content.trim();
+
+			buffer.append(trimmed);
+
+			if (fParent.hasBorder(BORDER_UPPER)) {
+
+				for (int character= 0; character < length - trimmed.length() + start.length(); character++)
+					buffer.append(filler);
+			}
+
+			buffer.append(fParent.getDelimiter());
+			buffer.append(indentation);
+			buffer.append(content);
+		}
+		fParent.logEdit(buffer.toString(), 0, range.getOffset());
+	}
+
+	/**
+	 * Returns the line prefix of content lines.
+	 * 
+	 * @return line prefix of content lines
+	 */
+	protected abstract String getContentPrefix();
+
+	/**
+	 * Returns the line prefix of end lines.
+	 * 
+	 * @return line prefix of end lines
+	 */
+	protected abstract String getEndingPrefix();
+
+	/**
+	 * Returns the first comment range in this comment line.
+	 * 
+	 * @return the first comment range
+	 */
+	protected final CommentRange getFirst() {
+		return (CommentRange)fRanges.getFirst();
+	}
+
+	/**
+	 * Returns the indentation reference string for this line.
+	 * 
+	 * @return the indentation reference string for this line
+	 */
+	protected String getIndentationReference() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the last comment range in this comment line.
+	 * 
+	 * @return the last comment range
+	 */
+	protected final CommentRange getLast() {
+		return (CommentRange)fRanges.getLast();
+	}
+
+	/**
+	 * Returns the parent comment region of this comment line.
+	 * 
+	 * @return the parent comment region
+	 */
+	protected final CommentRegion getParent() {
+		return fParent;
+	}
+
+	/**
+	 * Returns the number of comment ranges in this comment line.
+	 * 
+	 * @return the number of ranges in this line
+	 */
+	protected final int getSize() {
+		return fRanges.size();
+	}
+
+	/**
+	 * Returns the line prefix of start lines.
+	 * 
+	 * @return line prefix of start lines
+	 */
+	protected abstract String getStartingPrefix();
+
+	/**
+	 * Is the attribute <code>attribute</code> true?
+	 * 
+	 * @param attribute the attribute to get.
+	 * @return <code>true</code> iff this attribute is <code>true</code>,
+	 *         <code>false</code> otherwise.
+	 */
+	protected final boolean hasAttribute(final int attribute) {
+		return (fAttributes & attribute) == attribute;
+	}
+
+	/**
+	 * Scans this comment line for comment range boundaries.
+	 * 
+	 * @param line the index of this line in the comment region
+	 */
+	protected abstract void scanLine(final int line);
+
+	/**
+	 * Set the attribute <code>attribute</code> to true.
+	 * 
+	 * @param attribute the attribute to set.
+	 */
+	protected final void setAttribute(final int attribute) {
+		fAttributes |= attribute;
+	}
+
+	/**
+	 * Tokenizes this comment line into comment ranges
+	 * 
+	 * @param line the index of this line in the comment region
+	 */
+	protected void tokenizeLine(final int line) {
+
+		int offset= 0;
+		int index= offset;
+
+		final CommentRange range= (CommentRange)fRanges.get(0);
+		final int begin= range.getOffset();
+
+		final String content= fParent.getText(begin, range.getLength());
+		final int length= content.length();
+
+		while (offset < length) {
+
+			while (offset < length && Character.isWhitespace(content.charAt(offset)))
+				offset++;
+
+			index= offset;
+
+			while (index < length && !Character.isWhitespace(content.charAt(index)))
+				index++;
+
+			if (index - offset > 0) {
+				fParent.append(new CommentRange(begin + offset, index - offset));
+
+				offset= index;
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentRange.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentRange.java
new file mode 100644
index 0000000..c007831
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentRange.java
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.Position;
+
+/**
+ * Range in a comment region in comment region coordinates.
+ * 
+ * @since 3.0
+ */
+public class CommentRange extends Position implements ICommentAttributes, IHtmlTagDelimiters {
+
+	/** The attributes of this range */
+	private int fAttributes= 0;
+
+	/**
+	 * Creates a new comment range.
+	 * 
+	 * @param position offset of the range
+	 * @param count length of the range
+	 */
+	public CommentRange(final int position, final int count) {
+		super(position, count);
+	}
+
+	/**
+	 * Is the attribute <code>attribute</code> true?
+	 * 
+	 * @param attribute the attribute to get
+	 * @return <code>true</code> iff this attribute is <code>true</code>,
+	 *         <code>false</code> otherwise
+	 */
+	protected final boolean hasAttribute(final int attribute) {
+		return (fAttributes & attribute) == attribute;
+	}
+
+	/**
+	 * Does this comment range contain a closing HTML tag?
+	 * 
+	 * @param token token belonging to the comment range
+	 * @param tag the HTML tag to check
+	 * @return <code>true</code> iff this comment range contains a closing
+	 *         html tag, <code>false</code> otherwise
+	 */
+	protected final boolean isClosingTag(final String token, final String tag) {
+
+		boolean result= token.startsWith(HTML_CLOSE_PREFIX) && token.charAt(token.length() - 1) == HTML_TAG_POSTFIX;
+		if (result) {
+
+			setAttribute(COMMENT_CLOSE);
+			result= token.substring(HTML_CLOSE_PREFIX.length(), token.length() - 1).equals(tag);
+		}
+		return result;
+	}
+
+	/**
+	 * Does this comment range contain an opening HTML tag?
+	 * 
+	 * @param token token belonging to the comment range
+	 * @param tag the HTML tag to check
+	 * @return <code>true</code> iff this comment range contains an
+	 *         opening html tag, <code>false</code> otherwise
+	 */
+	protected final boolean isOpeningTag(final String token, final String tag) {
+
+		boolean result= token.length() > 0 && token.charAt(0) == HTML_TAG_PREFIX && !token.startsWith(HTML_CLOSE_PREFIX) && token.charAt(token.length() - 1) == HTML_TAG_POSTFIX;
+		if (result) {
+
+			setAttribute(COMMENT_OPEN);
+			result= token.startsWith(tag, 1);
+		}
+		return result;
+	}
+
+	/**
+	 * Mark the comment range with the occurred HTML tags.
+	 * 
+	 * @param tags the HTML tags to test for their occurrence
+	 * @param token token belonging to the comment range
+	 * @param attribute attribute to set if a HTML tag is present
+	 * @param open <code>true</code> iff opening tags should be marked,
+	 *                <code>false</code> otherwise
+	 * @param close <code>true</code> iff closing tags should be marked,
+	 *                <code>false</code> otherwise
+	 */
+	protected final void markHtmlTag(final String[] tags, final String token, final int attribute, final boolean open, final boolean close) {
+
+		if (token.charAt(0) == HTML_TAG_PREFIX && token.charAt(token.length() - 1) == HTML_TAG_POSTFIX) {
+
+			String tag= null;
+			boolean isOpen= false;
+			boolean isClose= false;
+
+			for (int index= 0; index < tags.length; index++) {
+
+				tag= tags[index];
+
+				isOpen= isOpeningTag(token, tag);
+				isClose= isClosingTag(token, tag);
+
+				if ((open && isOpen) || (close && isClose)) {
+
+					setAttribute(attribute);
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Mark the comment range with the occurred tags.
+	 * 
+	 * @param tags the tags to test for their occurrence
+	 * @param prefix the prefix which is common to all the tags to test
+	 * @param token the token belonging to the comment range
+	 * @param attribute attribute to set if a tag is present
+	 */
+	protected final void markPrefixTag(final String[] tags, final char prefix, final String token, final int attribute) {
+
+		if (token.charAt(0) == prefix) {
+
+			String tag= null;
+			for (int index= 0; index < tags.length; index++) {
+
+				tag= tags[index];
+				if (token.equals(tag)) {
+
+					setAttribute(attribute);
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Marks the comment range with the HTML range tag.
+	 * 
+	 * @param token the token belonging to the comment range
+	 * @param tag the HTML tag which confines the HTML range
+	 * @param level the nesting level of the current HTML range
+	 * @param key the key of the attribute to set if the comment range is in
+	 *                the HTML range
+	 * @param html <code>true</code> iff the HTML tags in this HTML range
+	 *                should be marked too, <code>false</code> otherwise
+	 * @return the new nesting level of the HTML range
+	 */
+	protected final int markTagRange(final String token, final String tag, int level, final int key, final boolean html) {
+
+		if (isOpeningTag(token, tag)) {
+			if (level++ > 0)
+				setAttribute(key);
+		} else if (isClosingTag(token, tag)) {
+			if (--level > 0)
+				setAttribute(key);
+		} else if (level > 0) {
+			if (html || !hasAttribute(COMMENT_HTML))
+				setAttribute(key);
+		}
+		return level;
+	}
+
+	/**
+	 * Moves this comment range.
+	 * 
+	 * @param delta the delta to move the range
+	 */
+	public final void move(final int delta) {
+		offset += delta;
+	}
+
+	/**
+	 * Set the attribute <code>attribute</code> to true.
+	 * 
+	 * @param attribute the attribute to set.
+	 */
+	protected final void setAttribute(final int attribute) {
+		fAttributes |= attribute;
+	}
+
+	/**
+	 * Trims this comment range at the beginning.
+	 * 
+	 * @param delta amount to trim the range
+	 */
+	public final void trimBegin(final int delta) {
+		offset += delta;
+		length -= delta;
+	}
+
+	/**
+	 * Trims this comment range at the end.
+	 * 
+	 * @param delta amount to trim the range
+	 */
+	public final void trimEnd(final int delta) {
+		length += delta;
+	}
+	
+	/*
+	 * @see java.lang.Object#toString()
+	 * @since 3.1
+	 */
+	public String toString() {
+		List attributes= new ArrayList();
+		if (hasAttribute(COMMENT_BLANKLINE))
+			attributes.add("COMMENT_BLANKLINE"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_BREAK))
+			attributes.add("COMMENT_BREAK"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_CLOSE))
+			attributes.add("COMMENT_CLOSE"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_CODE))
+			attributes.add("COMMENT_CODE"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_HTML))
+			attributes.add("COMMENT_HTML"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_IMMUTABLE))
+			attributes.add("COMMENT_IMMUTABLE"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_NEWLINE))
+			attributes.add("COMMENT_NEWLINE"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_OPEN))
+			attributes.add("COMMENT_OPEN"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_PARAGRAPH))
+			attributes.add("COMMENT_PARAGRAPH"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_PARAMETER))
+			attributes.add("COMMENT_PARAMETER"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_ROOT))
+			attributes.add("COMMENT_ROOT"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_SEPARATOR))
+			attributes.add("COMMENT_SEPARATOR"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_FIRST_TOKEN))
+			attributes.add("COMMENT_FIRST_TOKEN"); //$NON-NLS-1$
+		if (hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER))
+			attributes.add("COMMENT_STARTS_WITH_RANGE_DELIMITER"); //$NON-NLS-1$
+		
+		StringBuffer buf= new StringBuffer("CommentRange [" + offset + "+" + length + "] {"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		for (Iterator it= attributes.iterator(); it.hasNext();) {
+			String string= (String) it.next();
+			buf.append(string);
+			if (it.hasNext())
+				buf.append(", "); //$NON-NLS-1$
+		}
+		
+		return buf.toString() + "}"; //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentRegion.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentRegion.java
new file mode 100644
index 0000000..90eb818
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/CommentRegion.java
@@ -0,0 +1,593 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+
+import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
+import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
+import org.eclipse.jdt.internal.formatter.Scribe;
+
+/**
+ * Comment region in a source code document.
+ * 
+ * @since 3.0
+ */
+public class CommentRegion extends Position implements IHtmlTagDelimiters, IBorderAttributes, ICommentAttributes {
+
+	/** Default comment range delimiter */
+	protected static final String COMMENT_RANGE_DELIMITER= " "; //$NON-NLS-1$
+
+	/** Default line prefix length */
+	private static final int COMMENT_PREFIX_LENGTH= 3;
+
+	/** The borders of this region */
+	private int fBorders= 0;
+
+	/** Should all blank lines be cleared during formatting? */
+	private final boolean fClear;
+
+	/** The line delimiter used in this comment region */
+	private final String fDelimiter;
+
+	/** The document to format */
+	private final IDocument fDocument;
+
+	/** The lines in this comment region */
+	private final LinkedList fLines= new LinkedList();
+	
+	/** The formatting preferences */
+	protected final DefaultCodeFormatterOptions preferences;
+	
+	/** The comment ranges in this comment region */
+	private final LinkedList fRanges= new LinkedList();
+
+	/** Is this comment region a single line region? */
+	private final boolean fSingleLine;
+
+	/** Number of spaces representing tabulator */
+	private int fTabSize;
+
+	/**
+	 * <code>true</code> if tabs, not spaces, should be used for indentation
+	 * @since 3.1
+	 */
+	private boolean fUseTab;
+	
+	/** the scribe used to create edits */
+	protected Scribe scribe;
+
+	/**
+	 * Creates a new comment region.
+	 * 
+	 * @param document the document which contains the comment region
+	 * @param position the position of this comment region in the document
+	 * @param formatter the given code formatter
+	 */
+	public CommentRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
+		super(position.getOffset(), position.getLength());
+
+		this.preferences = formatter.preferences;
+		fDelimiter = this.preferences.line_separator;
+		fDocument= document;
+		
+		fClear= this.preferences.comment_clear_blank_lines;
+		
+		fTabSize= this.preferences.tab_size;
+		fUseTab = this.preferences.tab_char == DefaultCodeFormatterOptions.TAB;
+
+		this.scribe = formatter.scribe;
+
+		final ILineTracker tracker= new DefaultLineTracker();
+
+		IRegion range= null;
+		CommentLine line= null;
+
+		tracker.set(getText(0, getLength()));
+		final int lines= tracker.getNumberOfLines();
+
+		fSingleLine= lines == 1;
+
+		try {
+
+			for (int index= 0; index < lines; index++) {
+
+				range= tracker.getLineInformation(index);
+				line= createLine();
+				line.append(new CommentRange(range.getOffset(), range.getLength()));
+
+				fLines.add(line);
+			}
+
+		} catch (BadLocationException exception) {
+			// Should not happen
+		}
+	}
+
+	/**
+	 * Appends the comment range to this comment region.
+	 * 
+	 * @param range comment range to append to this comment region
+	 */
+	protected final void append(final CommentRange range) {
+		fRanges.addLast(range);
+	}
+
+	/**
+	 * Can the comment range be appended to the comment line?
+	 * 
+	 * @param line comment line where to append the comment range
+	 * @param previous comment range which is the predecessor of the current
+	 *                comment range
+	 * @param next comment range to test whether it can be appended to the
+	 *                comment line
+	 * @param index amount of space in the comment line used by already
+	 *                inserted comment ranges
+	 * @param width the maximal width of text in this comment region
+	 *                measured in average character widths
+	 * @return <code>true</code> iff the comment range can be added to the
+	 *         line, <code>false</code> otherwise
+	 */
+	protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, final int width) {
+		return index == 0 || index + next.getLength() <= width;
+	}
+
+	/**
+	 * Can the whitespace between the two comment ranges be formatted?
+	 * 
+	 * @param previous previous comment range which was already formatted,
+	 *                can be <code>null</code>
+	 * @param next next comment range to be formatted
+	 * @return <code>true</code> iff the next comment range can be
+	 *         formatted, <code>false</code> otherwise.
+	 */
+	protected boolean canFormat(final CommentRange previous, final CommentRange next) {
+		return previous != null;
+	}
+
+	/**
+	 * Formats the comment region with the given indentation level.
+	 * 
+	 * @param indentationLevel the indentation level
+	 * @return the resulting text edit of the formatting process
+	 * @since 3.1
+	 */
+	public final TextEdit format(int indentationLevel, boolean returnEdit) {
+		final String probe= getText(0, CommentLine.NON_FORMAT_START_PREFIX.length());
+		if (!probe.startsWith(CommentLine.NON_FORMAT_START_PREFIX)) {
+
+			int margin= this.preferences.comment_line_length;
+			String indentation= computeIndentation(indentationLevel);
+			margin= Math.max(COMMENT_PREFIX_LENGTH + 1, margin - stringToLength(indentation) - COMMENT_PREFIX_LENGTH);
+
+			tokenizeRegion();
+			markRegion();
+			wrapRegion(margin);
+			formatRegion(indentation, margin);
+
+		}
+		if (returnEdit) {
+			return this.scribe.getRootEdit();
+		}
+		return null;
+	}
+
+	/**
+	 * Formats this comment region.
+	 * 
+	 * @param indentation the indentation of this comment region
+	 * @param width the maximal width of text in this comment region
+	 *                measured in average character widths
+	 */
+	protected void formatRegion(final String indentation, final int width) {
+
+		final int last= fLines.size() - 1;
+		if (last >= 0) {
+
+			CommentLine lastLine= (CommentLine)fLines.get(last);
+			CommentRange lastRange= lastLine.getLast();
+			lastLine.formatLowerBorder(lastRange, indentation, width);
+
+			CommentLine previous;
+			CommentLine next= null;
+			CommentRange range= null;
+			for (int line= last; line >= 0; line--) {
+
+				previous= next;
+				next= (CommentLine)fLines.get(line);
+
+				range= next.formatLine(previous, range, indentation, line);
+			}
+			next.formatUpperBorder(range, indentation, width);
+		}
+	}
+
+	/**
+	 * Returns the line delimiter used in this comment region.
+	 * 
+	 * @return the line delimiter for this comment region
+	 */
+	protected final String getDelimiter() {
+		return fDelimiter;
+	}
+
+	/**
+	 * Returns the line delimiter used in this comment line break.
+	 * 
+	 * @param predecessor the predecessor comment line after the line break
+	 * @param successor the successor comment line before the line break
+	 * @param previous the comment range after the line break
+	 * @param next the comment range before the line break
+	 * @param indentation indentation of the formatted line break
+	 * @return the line delimiter for this comment line break
+	 */
+	protected String getDelimiter(final CommentLine predecessor, final CommentLine successor, final CommentRange previous, final CommentRange next, final String indentation) {
+		return fDelimiter + indentation + successor.getContentPrefix();
+	}
+
+	/**
+	 * Returns the range delimiter for this comment range break.
+	 * 
+	 * @param previous the previous comment range to the right of the range
+	 *                delimiter
+	 * @param next the next comment range to the left of the range delimiter
+	 * @return the delimiter for this comment range break
+	 */
+	protected String getDelimiter(final CommentRange previous, final CommentRange next) {
+		return COMMENT_RANGE_DELIMITER;
+	}
+
+	/**
+	 * Returns the document of this comment region.
+	 * 
+	 * @return the document of this region
+	 */
+	protected final IDocument getDocument() {
+		return fDocument;
+	}
+
+	/**
+	 * Returns the comment ranges in this comment region
+	 * 
+	 * @return the comment ranges in this region
+	 */
+	protected final LinkedList getRanges() {
+		return fRanges;
+	}
+
+	/**
+	 * Returns the number of comment lines in this comment region.
+	 * 
+	 * @return the number of lines in this comment region
+	 */
+	protected final int getSize() {
+		return fLines.size();
+	}
+
+	/**
+	 * Returns the text of this comment region in the indicated range.
+	 * 
+	 * @param position the offset of the comment range to retrieve in
+	 *                comment region coordinates
+	 * @param count the length of the comment range to retrieve
+	 * @return the content of this comment region in the indicated range
+	 */
+	protected final String getText(final int position, final int count) {
+
+		String content= ""; //$NON-NLS-1$
+		try {
+			content= fDocument.get(getOffset() + position, count);
+		} catch (BadLocationException exception) {
+			// Should not happen
+		}
+		return content;
+	}
+
+	/**
+	 * Does the border <code>border</code> exist?
+	 * 
+	 * @param border the type of the border, must be a border attribute of
+	 *                <code>CommentRegion</code>
+	 * @return <code>true</code> iff this border exists,
+	 *         <code>false</code> otherwise
+	 */
+	protected final boolean hasBorder(final int border) {
+		return (fBorders & border) == border;
+	}
+
+	/**
+	 * Does the comment range consist of letters and digits only?
+	 * 
+	 * @param range the comment range to text
+	 * @return <code>true</code> iff the comment range consists of letters
+	 *         and digits only, <code>false</code> otherwise
+	 */
+	protected final boolean isAlphaNumeric(final CommentRange range) {
+
+		final String token= getText(range.getOffset(), range.getLength());
+
+		for (int index= 0; index < token.length(); index++) {
+			if (!Character.isLetterOrDigit(token.charAt(index)))
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Does the comment range contain no letters and digits?
+	 * 
+	 * @param range the comment range to text
+	 * @return <code>true</code> iff the comment range contains no letters
+	 *         and digits, <code>false</code> otherwise
+	 */
+	protected final boolean isNonAlphaNumeric(final CommentRange range) {
+
+		final String token= getText(range.getOffset(), range.getLength());
+
+		for (int index= 0; index < token.length(); index++) {
+			if (Character.isLetterOrDigit(token.charAt(index)))
+				return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Should blank lines be cleared during formatting?
+	 * 
+	 * @return <code>true</code> iff blank lines should be cleared,
+	 *         <code>false</code> otherwise
+	 */
+	protected final boolean isClearLines() {
+		return fClear;
+	}
+
+	/**
+	 * Is this comment region a single line region?
+	 * 
+	 * @return <code>true</code> iff this region is single line,
+	 *         <code>false</code> otherwise
+	 */
+	protected final boolean isSingleLine() {
+		return fSingleLine;
+	}
+
+	/**
+	 * Logs a text edit operation occurred during the formatting process
+	 * 
+	 * @param change the changed text
+	 * @param position offset measured in comment region coordinates where
+	 *                to apply the changed text
+	 * @param count length of the range where to apply the changed text
+	 */
+	protected final void logEdit(final String change, final int position, final int count) {
+		try {
+			final int base= getOffset() + position;
+			final String content= fDocument.get(base, count);
+
+			if (!change.equals(content)) {
+				if (count > 0) {
+					this.scribe.addReplaceEdit(base, base + count - 1, change);
+				} else {
+					this.scribe.addInsertEdit(base, change);
+				}
+			}
+		} catch (BadLocationException exception) {
+			// Should not happen
+			CommentFormatterUtil.log(exception);
+		} catch (MalformedTreeException exception) {
+			// Do nothing
+			CommentFormatterUtil.log(exception);
+		}
+	}
+
+	/**
+	 * Marks the comment ranges in this comment region.
+	 */
+	protected void markRegion() {
+		// Do nothing
+	}
+
+	/**
+	 * Set the border type <code>border</code> to true.
+	 * 
+	 * @param border the type of the border. Must be a border attribute of
+	 *                <code>CommentRegion</code>
+	 */
+	protected final void setBorder(final int border) {
+		fBorders |= border;
+	}
+
+	/**
+	 * Returns the indentation of the given indentation level.
+	 * 
+	 * @param indentationLevel the indentation level
+	 * @return the indentation of the given indentation level
+	 * @since 3.1
+	 */
+	private String computeIndentation(int indentationLevel) {
+		return replicate(fUseTab ? "\t" : replicate(" ", fTabSize), indentationLevel);  //$NON-NLS-1$//$NON-NLS-2$
+	}
+	
+	/**
+	 * Returns the given string n-times replicated.
+	 * 
+	 * @param string the string
+	 * @param n n
+	 * @return the given string n-times replicated
+	 * @since 3.1
+	 */
+	private String replicate(String string, int n) {
+		StringBuffer buffer= new StringBuffer(n*string.length());
+		for (int i= 0; i < n; i++)
+			buffer.append(string);
+		return buffer.toString();
+	}
+
+	/**
+	 * Computes the equivalent indentation for a string
+	 * 
+	 * @param reference the string to compute the indentation for
+	 * @param tabs <code>true</code> iff the indentation should use tabs,
+	 *                <code>false</code> otherwise.
+	 * @return the indentation string
+	 */
+	protected final String stringToIndent(final String reference, final boolean tabs) {
+
+		int spaceWidth= 1;
+		int referenceWidth= expandTabs(reference).length();
+
+		final StringBuffer buffer= new StringBuffer();
+		final int spaces= referenceWidth / spaceWidth;
+
+		if (tabs) {
+
+			final int count= spaces / fTabSize;
+			final int modulo= spaces % fTabSize;
+
+			for (int index= 0; index < count; index++)
+				buffer.append('\t');
+
+			for (int index= 0; index < modulo; index++)
+				buffer.append(' ');
+
+		} else {
+
+			for (int index= 0; index < spaces; index++)
+				buffer.append(' ');
+		}
+		return buffer.toString();
+	}
+
+	/**
+	 * Returns the length of the string in expanded characters.
+	 * 
+	 * @param reference the string to get the length for
+	 * @return the length of the string in expanded characters
+	 */
+	protected final int stringToLength(final String reference) {
+		return expandTabs(reference).length();
+	}
+
+	/**
+	 * Expands the given string's tabs according to the given tab size.
+	 * 
+	 * @param string the string
+	 * @return the expanded string
+	 * @since 3.1
+	 */
+	private String expandTabs(String string) {
+		StringBuffer expanded= new StringBuffer();
+		for (int i= 0, n= string.length(), chars= 0; i < n; i++) {
+			char ch= string.charAt(i);
+			if (ch == '\t') {
+				for (; chars < fTabSize; chars++)
+					expanded.append(' ');
+				chars= 0;
+			} else {
+				expanded.append(ch);
+				chars++;
+				if (chars >= fTabSize)
+					chars= 0;
+			}
+		
+		}
+		return expanded.toString();
+	}
+
+	/**
+	 * Tokenizes the comment region.
+	 */
+	protected void tokenizeRegion() {
+
+		int index= 0;
+		CommentLine line= null;
+
+		for (final Iterator iterator= fLines.iterator(); iterator.hasNext(); index++) {
+
+			line= (CommentLine)iterator.next();
+
+			line.scanLine(index);
+			line.tokenizeLine(index);
+		}
+	}
+
+	/**
+	 * Wraps the comment ranges in this comment region into comment lines.
+	 * 
+	 * @param width the maximal width of text in this comment region
+	 *                measured in average character widths
+	 */
+	protected void wrapRegion(final int width) {
+
+		fLines.clear();
+
+		int index= 0;
+		boolean adapted= false;
+
+		CommentLine successor= null;
+		CommentLine predecessor= null;
+
+		CommentRange previous= null;
+		CommentRange next= null;
+
+		while (!fRanges.isEmpty()) {
+
+			index= 0;
+			adapted= false;
+
+			predecessor= successor;
+			successor= createLine();
+			fLines.add(successor);
+
+			while (!fRanges.isEmpty()) {
+				next= (CommentRange)fRanges.getFirst();
+
+				if (canAppend(successor, previous, next, index, width)) {
+
+					if (!adapted && predecessor != null) {
+
+						successor.adapt(predecessor);
+						adapted= true;
+					}
+
+					fRanges.removeFirst();
+					successor.append(next);
+
+					index += (next.getLength() + 1);
+					previous= next;
+				} else
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Creates a new line for this region.
+	 * 
+	 * @return a new line for this region
+	 * @since 3.1
+	 */
+	protected CommentLine createLine() {
+		return new SingleCommentLine(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/HTMLEntity2JavaReader.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/HTMLEntity2JavaReader.java
new file mode 100644
index 0000000..94acef6
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/HTMLEntity2JavaReader.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <code>SubstitutionTextReader</code> that will substitute plain text values
+ * for html entities encountered in the original text. Line breaks and
+ * whitespace are preserved.
+ * 
+ * @since 3.0
+ */
+public class HTMLEntity2JavaReader extends SubstitutionTextReader {
+
+	/** The hard-coded entity map. */
+	private static final Map fgEntityLookup;
+	
+	static {
+		fgEntityLookup= new HashMap(7);
+		fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$
+		fgEntityLookup.put("quot", "\""); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Creates a new instance that will read from <code>reader</code>
+	 * 
+	 * @param reader the source reader
+	 */
+	public HTMLEntity2JavaReader(Reader reader) {
+		super(reader);
+		setSkipWhitespace(false);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
+	 */
+	protected String computeSubstitution(int c) throws IOException {
+		if (c == '&')
+			return processEntity();
+		return null;
+	}
+
+	/**
+	 * Replaces an HTML entity body (without &amp; and ;) with its
+	 * plain/text (or plain/java) counterpart.
+	 * 
+	 * @param symbol the entity body to resolve
+	 * @return the plain/text counterpart of <code>symbol</code>
+	 */
+	protected String entity2Text(String symbol) {
+		if (symbol.length() > 1 && symbol.charAt(0) == '#') {
+			int ch;
+			try {
+				if (symbol.charAt(1) == 'x') {
+					ch= Integer.parseInt(symbol.substring(2), 16);
+				} else {
+					ch= Integer.parseInt(symbol.substring(1), 10);
+				}
+				return " " + (char) ch; //$NON-NLS-1$
+			} catch (NumberFormatException e) {
+				// ignore
+			}
+		} else {
+			String str= (String) fgEntityLookup.get(symbol);
+			if (str != null) {
+				return str;
+			}
+		}
+		return "&" + symbol; // not found //$NON-NLS-1$
+	}
+
+	/**
+	 * Reads an HTML entity from the stream and returns its plain/text
+	 * counterpart.
+	 * 
+	 * @return an entity read from the stream, or the stream content.
+	 * @throws IOException if the underlying reader throws one
+	 */
+	private String processEntity() throws IOException {
+		StringBuffer buf= new StringBuffer();
+		int ch= nextChar();
+		while (Character.isLetterOrDigit((char) ch) || ch == '#') {
+			buf.append((char) ch);
+			ch= nextChar();
+		}
+		if (ch == ';')
+			return entity2Text(buf.toString());
+		buf.insert(0, '&');
+		if (ch != -1)
+			buf.append((char) ch);
+		return buf.toString();
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IBorderAttributes.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IBorderAttributes.java
new file mode 100644
index 0000000..f7919b6
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IBorderAttributes.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * Comment region border attributes.
+ * 
+ * @since 3.0
+ */
+public interface IBorderAttributes {
+
+	/** Region has lower border attribute */
+	public static final int BORDER_LOWER= 1 << 0;
+
+	/** Region has upper border attribute */
+	public static final int BORDER_UPPER= 1 << 1;
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/ICommentAttributes.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/ICommentAttributes.java
new file mode 100644
index 0000000..45f493e
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/ICommentAttributes.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * General comment range attributes.
+ * 
+ * @since 3.0
+ */
+public interface ICommentAttributes {
+
+	/** Range has blank line attribute */
+	public static final int COMMENT_BLANKLINE= 1 << 1;
+
+	/** Range has line break attribute */
+	public static final int COMMENT_BREAK= 1 << 2;
+
+	/** Range has close tag attribute */
+	public static final int COMMENT_CLOSE= 1 << 3;
+
+	/** Range has source code attribute */
+	public static final int COMMENT_CODE= 1 << 4;
+
+	/** Range has html tag attribute */
+	public static final int COMMENT_HTML= 1 << 5;
+
+	/** Range has the immutable region attribute */
+	public static final int COMMENT_IMMUTABLE= 1 << 6;
+
+	/** Range has new line attribute */
+	public static final int COMMENT_NEWLINE= 1 << 7;
+
+	/** Range has open tag attribute */
+	public static final int COMMENT_OPEN= 1 << 8;
+
+	/** Range has paragraph attribute */
+	public static final int COMMENT_PARAGRAPH= 1 << 9;
+
+	/** Range has parameter tag attribute */
+	public static final int COMMENT_PARAMETER= 1 << 10;
+
+	/** Range has root tag attribute */
+	public static final int COMMENT_ROOT= 1 << 11;
+
+	/** Range has paragraph separator attribute */
+	public static final int COMMENT_SEPARATOR= 1 << 12;
+
+	/** Range is the first token on the line in the original source */
+	public static final int COMMENT_FIRST_TOKEN= 1 << 13;
+	
+	/**
+	 * Range was preceded by whitespace / line delimiters
+	 * @since 3.1
+	 */
+	public static final int COMMENT_STARTS_WITH_RANGE_DELIMITER= 1 << 14;
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IHtmlTagDelimiters.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IHtmlTagDelimiters.java
new file mode 100644
index 0000000..853e412
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IHtmlTagDelimiters.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * Html tag constants.
+ * 
+ * @since 3.0
+ */
+public interface IHtmlTagDelimiters {
+
+	/** Html tag close prefix */
+	public static final String HTML_CLOSE_PREFIX= "</"; //$NON-NLS-1$
+
+	/** Html tag postfix */
+	public static final char HTML_TAG_POSTFIX= '>';
+
+	/** Html tag prefix */
+	public static final char HTML_TAG_PREFIX= '<';
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IJavaDocTagConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IJavaDocTagConstants.java
new file mode 100644
index 0000000..7effbc1
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/IJavaDocTagConstants.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * Javadoc tag constants.
+ * 
+ * @since 3.0
+ */
+public interface IJavaDocTagConstants {
+
+	/** Javadoc break tags */
+	public static final String[] JAVADOC_BREAK_TAGS= new String[] { "dd", "dt", "li", "td", "th", "tr", "h1", "h2", "h3", "h4", "h5", "h6", "q" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$
+
+	/** Javadoc single break tag */
+	public static final String[] JAVADOC_SINGLE_BREAK_TAG= new String[] { "br" }; //$NON-NLS-1$
+
+	/** Javadoc code tags */
+	public static final String[] JAVADOC_CODE_TAGS= new String[] { "pre" }; //$NON-NLS-1$
+
+	/** Javadoc immutable tags */
+	public static final String[] JAVADOC_IMMUTABLE_TAGS= new String[] { "code", "em", "pre", "q", "tt" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+	/** Javadoc new line tags */
+	public static final String[] JAVADOC_NEWLINE_TAGS= new String[] { "dd", "dt", "li", "td", "th", "tr", "h1", "h2", "h3", "h4", "h5", "h6", "q" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$
+
+	/** Javadoc parameter tags */
+	public static final String[] JAVADOC_PARAM_TAGS= new String[] { "@exception", "@param", "@serialField", "@throws" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+	/** Javadoc separator tags */
+	public static final String[] JAVADOC_SEPARATOR_TAGS= new String[] { "dl", "hr", "nl", "p", "pre", "ul", "ol" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+
+	/** Javadoc tag prefix */
+	public static final char JAVADOC_TAG_PREFIX= '@';
+
+	/** Link tag postfix */
+	public static final char LINK_TAG_POSTFIX= '}';
+
+	/** Link tag prefix */
+	public static final String LINK_TAG_PREFIX= "{@"; //$NON-NLS-1$
+
+	/** Comment root tags */
+	public static final String[] COMMENT_ROOT_TAGS= new String[] { "@deprecated", "@see", "@since", "@version" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+	/** Tag prefix of comment tags */
+	public static final char COMMENT_TAG_PREFIX= '@';
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/Java2HTMLEntityReader.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/Java2HTMLEntityReader.java
new file mode 100644
index 0000000..432b4a8
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/Java2HTMLEntityReader.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <code>SubstitutionTextReader</code> that will substitute html entities for
+ * html symbols encountered in the original text. Line breaks and whitespaces
+ * are preserved.
+ * 
+ * @since 3.0
+ */
+public class Java2HTMLEntityReader extends SubstitutionTextReader {
+
+	/** The hardcoded entity map. */
+	private static final Map fgEntityLookup;
+	
+	static {
+		fgEntityLookup= new HashMap(7);
+		fgEntityLookup.put("<", "&lt;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put(">", "&gt;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("&", "&amp;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("^", "&circ;"); //$NON-NLS-1$ //$NON-NLS-2$
+		fgEntityLookup.put("~", "&tilde;"); //$NON-NLS-2$ //$NON-NLS-1$
+		fgEntityLookup.put("\"", "&quot;"); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
+	/**
+	 * Creates a new instance that will read from <code>reader</code>
+	 * 
+	 * @param reader the source reader
+	 */
+	public Java2HTMLEntityReader(Reader reader) {
+		super(reader);
+		setSkipWhitespace(false);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
+	 */
+	protected String computeSubstitution(int c) {
+		String lookup= (String) fgEntityLookup.get(String.valueOf((char) c));
+		return lookup;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocLine.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocLine.java
new file mode 100644
index 0000000..7815009
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocLine.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * Javadoc comment line in a comment region.
+ * 
+ * @since 3.0
+ */
+public class JavaDocLine extends MultiCommentLine {
+
+	/** Line prefix of javadoc start lines */
+	public static final String JAVADOC_START_PREFIX= "/**"; //$NON-NLS-1$
+
+	/**
+	 * Creates a new javadoc line.
+	 * 
+	 * @param region comment region to create the line for
+	 */
+	protected JavaDocLine(final CommentRegion region) {
+		super(region);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#formatUpperBorder(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String, int)
+	 */
+	protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) {
+
+		final CommentRegion parent= getParent();
+
+		if (parent.isSingleLine() && parent.getSize() == 1) {
+			parent.logEdit(getStartingPrefix() + CommentRegion.COMMENT_RANGE_DELIMITER, 0, range.getOffset());
+		} else
+			super.formatUpperBorder(range, indentation, length);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getStartingPrefix()
+	 */
+	protected String getStartingPrefix() {
+		return JAVADOC_START_PREFIX;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java
new file mode 100644
index 0000000..5767dc7
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/JavaDocRegion.java
@@ -0,0 +1,354 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.text.edits.TextEdit;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.TextUtilities;
+
+import org.eclipse.jdt.core.formatter.CodeFormatter;
+import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
+
+
+/**
+ * Javadoc region in a source code document.
+ * 
+ * @since 3.0
+ */
+public class JavaDocRegion extends MultiCommentRegion implements IJavaDocTagConstants {
+
+	/** The positions of code ranges */
+	private final ArrayList fCodePositions= new ArrayList();
+	 
+	/** Should HTML tags be formatted? */
+	private final boolean fFormatHtml;
+
+	/** Should source code regions be formatted? */
+	private final boolean fFormatSource;
+	
+ 	/**
+	 * Creates a new Javadoc region.
+	 * 
+	 * @param document the document which contains the comment region
+	 * @param position the position of this comment region in the document
+	 * @param formatter the given formatter
+	 */	
+	public JavaDocRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
+		super(document, position, formatter);
+
+		fFormatSource= this.preferences.comment_format_source;
+		fFormatHtml= this.preferences.comment_format_html;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canFormat(org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange)
+	 */
+	protected boolean canFormat(final CommentRange previous, final CommentRange next) {
+		
+		if (previous != null) {
+			
+			final boolean isCurrentCode= next.hasAttribute(COMMENT_CODE);
+			final boolean isLastCode= previous.hasAttribute(COMMENT_CODE);
+			
+			final int base= getOffset();
+			
+			if (!isLastCode && isCurrentCode)
+				fCodePositions.add(new Position(base + previous.getOffset()));
+			else if (isLastCode && !isCurrentCode)
+				fCodePositions.add(new Position(base + next.getOffset() + next.getLength()));
+			
+			if (previous.hasAttribute(COMMENT_IMMUTABLE) && next.hasAttribute(COMMENT_IMMUTABLE))
+				return false;
+			
+			return true;
+		}
+		return false;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#formatRegion(java.lang.String, int)
+	 */
+	protected final void formatRegion(final String indentation, final int width) {
+	
+		super.formatRegion(indentation, width);
+		
+		if (fFormatSource) {
+			
+			try {
+				
+				if (fCodePositions.size() > 0) {
+					
+					int begin= 0;
+					int end= 0;
+					
+					Position position= null;
+					
+					final IDocument document= getDocument();
+					
+					for (int index= fCodePositions.size() - 1; index >= 0;) {
+						
+						position= (Position)fCodePositions.get(index--);
+						begin= position.getOffset();
+						
+						if (index >= 0) {
+							position= (Position)fCodePositions.get(index--);
+							end= position.getOffset();
+						} else {
+							/* 
+							 * Handle missing closing tag
+							 * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=57011
+							 */
+							position= null;
+							end= getOffset() + getLength() - MultiCommentLine.MULTI_COMMENT_END_PREFIX.trim().length();
+							while (end > begin && Character.isWhitespace(document.getChar(end - 1)))
+								end--;
+						}
+						
+						String snippet= document.get(begin, end - begin);
+						snippet= preprocessCodeSnippet(snippet);
+						snippet= formatCodeSnippet(snippet);
+						snippet= postprocessCodeSnippet(snippet, indentation);
+						
+						logEdit(snippet, begin - getOffset(), end - begin);
+					}
+				}
+			} catch (BadLocationException e) {
+				// Can not happen
+				CommentFormatterUtil.log(e);
+			}
+		}
+	}
+
+	/**
+	 * Preprocess a given code snippet.
+	 * 
+	 * @param snippet the code snippet
+	 * @return the preprocessed code snippet
+	 */
+	private String preprocessCodeSnippet(String snippet) {
+		// strip content prefix
+		StringBuffer buffer= new StringBuffer();
+		ILineTracker tracker= new DefaultLineTracker();
+		String contentPrefix= MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX.trim();
+		
+		buffer.setLength(0);
+		buffer.append(snippet);
+		tracker.set(snippet);
+		for (int line= tracker.getNumberOfLines() - 1; line > 0; line--) {
+			int lineOffset;
+			try {
+				lineOffset= tracker.getLineOffset(line);
+			} catch (BadLocationException e) {
+				// Can not happen
+				CommentFormatterUtil.log(e);
+				return snippet;
+			}
+			int prefixOffset= buffer.indexOf(contentPrefix, lineOffset);
+			if (prefixOffset >= 0 && buffer.substring(lineOffset, prefixOffset).trim().length() == 0)
+				buffer.delete(lineOffset, prefixOffset + contentPrefix.length());
+		}
+		
+		return convertHtml2Java(buffer.toString());
+	}
+
+	/**
+	 * Format the given code snippet
+	 * 
+	 * @param snippet the code snippet
+	 * @return the formatted code snippet
+	 */
+	private String formatCodeSnippet(String snippet) {
+		String lineDelimiter= TextUtilities.getDefaultLineDelimiter(getDocument());
+		TextEdit edit= CommentFormatterUtil.format2(CodeFormatter.K_UNKNOWN, snippet, 0, lineDelimiter, this.preferences.getMap());
+		if (edit != null)
+			snippet= CommentFormatterUtil.evaluateFormatterEdit(snippet, edit, null);
+		return snippet;
+	}
+
+	/**
+	 * Postprocesses the given code snippet with the given indentation.
+	 * 
+	 * @param snippet the code snippet
+	 * @param indentation the indentation
+	 * @return the postprocessed code snippet
+	 */
+	private String postprocessCodeSnippet(String snippet, String indentation) {
+		// patch content prefix
+		StringBuffer buffer= new StringBuffer();
+		ILineTracker tracker= new DefaultLineTracker();
+		String patch= indentation + MultiCommentLine.MULTI_COMMENT_CONTENT_PREFIX;
+
+		buffer.setLength(0);
+		buffer.append(getDelimiter());
+		buffer.append(convertJava2Html(snippet));
+		buffer.append(getDelimiter());
+		tracker.set(buffer.toString());
+		
+		for (int line= tracker.getNumberOfLines() - 1; line > 0; line--)
+			try {
+				buffer.insert(tracker.getLineOffset(line), patch);
+			} catch (BadLocationException e) {
+				// Can not happen
+				CommentFormatterUtil.log(e);
+				return snippet;
+			}
+		
+		return buffer.toString();
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markHtmlRanges()
+	 */
+	protected final void markHtmlRanges() {
+
+		markTagRanges(JAVADOC_IMMUTABLE_TAGS, COMMENT_IMMUTABLE, true);
+
+		if (fFormatSource)
+			markTagRanges(JAVADOC_CODE_TAGS, COMMENT_CODE, false);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markHtmlTag(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
+	 */
+	protected final void markHtmlTag(final CommentRange range, final String token) {
+
+		if (range.hasAttribute(COMMENT_HTML)) {
+
+			range.markHtmlTag(JAVADOC_IMMUTABLE_TAGS, token, COMMENT_IMMUTABLE, true, true);
+			if (fFormatHtml) {
+
+				range.markHtmlTag(JAVADOC_SEPARATOR_TAGS, token, COMMENT_SEPARATOR, true, true);
+				range.markHtmlTag(JAVADOC_BREAK_TAGS, token, COMMENT_BREAK, false, true);
+				range.markHtmlTag(JAVADOC_SINGLE_BREAK_TAG, token, COMMENT_BREAK, true, false);
+				range.markHtmlTag(JAVADOC_NEWLINE_TAGS, token, COMMENT_NEWLINE, true, false);
+
+			} else
+				range.markHtmlTag(JAVADOC_CODE_TAGS, token, COMMENT_SEPARATOR, true, true);
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.MultiCommentRegion#markJavadocTag(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
+	 */
+	protected final void markJavadocTag(final CommentRange range, final String token) {
+
+		range.markPrefixTag(JAVADOC_PARAM_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_PARAMETER);
+
+		if (token.charAt(0) == JAVADOC_TAG_PREFIX && !range.hasAttribute(COMMENT_PARAMETER))
+			range.setAttribute(COMMENT_ROOT);
+	}
+
+	/**
+	 * Marks the comment region with the HTML range tag.
+	 * 
+	 * @param tags the HTML tag which confines the HTML range
+	 * @param attribute the attribute to set if the comment range is in the
+	 *                HTML range
+	 * @param html <code>true</code> iff the HTML tags in this HTML range
+	 *                should be marked too, <code>false</code> otherwise
+	 */
+	protected final void markTagRanges(final String[] tags, final int attribute, final boolean html) {
+		
+		int level= 0;
+		int count= 0;
+		String token= null;
+		CommentRange current= null;
+		
+		for (int index= 0; index < tags.length; index++) {
+			
+			level= 0;
+			for (final Iterator iterator= getRanges().iterator(); iterator.hasNext();) {
+				
+				current= (CommentRange)iterator.next();
+				count= current.getLength();
+				
+				if (count > 0 || level > 0) { // PR44035: when inside a tag, mark blank lines as well to get proper snippet formatting
+					
+					token= getText(current.getOffset(), current.getLength());
+					level= current.markTagRange(token, tags[index], level, attribute, html);
+				}
+			}
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canAppend(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, int, int)
+	 */
+	protected boolean canAppend(CommentLine line, CommentRange previous, CommentRange next, int index, int count) {
+		// don't append code sections
+		if (next.hasAttribute(COMMENT_CODE | COMMENT_FIRST_TOKEN) && line.getSize() != 0)
+			return false;
+		return super.canAppend(line, previous, next, index, count);
+	}
+
+	/**
+	 * Converts <code>formatted</code> into valid html code suitable to be
+	 * put inside &lt;pre&gt;&lt;/pre&gt; tags by replacing any html symbols
+	 * by the relevant entities.
+	 * 
+	 * @param formatted the formatted java code
+	 * @return html version of the formatted code
+	 */
+	private String convertJava2Html(String formatted) {
+		Java2HTMLEntityReader reader= new Java2HTMLEntityReader(new StringReader(formatted));
+		char[] buf= new char[256];
+		StringBuffer buffer= new StringBuffer();
+		int l;
+		try {
+			do {
+				l= reader.read(buf);
+				if (l != -1)
+					buffer.append(buf, 0, l);
+			} while (l > 0);
+			return buffer.toString();
+		} catch (IOException e) {
+			return formatted;
+		}
+	}
+
+	/**
+	 * Converts <code>html</code> into java code suitable for formatting
+	 * by replacing any html entities by their plain text representation.
+	 * 
+	 * @param html html code, may contain html entities
+	 * @return plain textified version of <code>html</code>
+	 */
+	private String convertHtml2Java(String html) {
+		HTMLEntity2JavaReader reader= new HTMLEntity2JavaReader(new StringReader(html));
+		char[] buf= new char[html.length()]; // html2text never gets longer, only shorter!
+		
+		try {
+			int read= reader.read(buf);
+			return new String(buf, 0, read);
+		} catch (IOException e) {
+			return html;
+		}
+	}
+	
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#createLine()
+	 * @since 3.1
+	 */
+	protected CommentLine createLine() {
+		return new JavaDocLine(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentLine.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentLine.java
new file mode 100644
index 0000000..2fd7fff
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentLine.java
@@ -0,0 +1,402 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+/**
+ * Multi-line comment line in a comment region.
+ * 
+ * @since 3.0
+ */
+public class MultiCommentLine extends CommentLine implements ICommentAttributes, IHtmlTagDelimiters, IJavaDocTagConstants {
+
+	/** Line prefix of multi-line comment content lines */
+	public static final String MULTI_COMMENT_CONTENT_PREFIX= " * "; //$NON-NLS-1$
+
+	/** Line prefix of multi-line comment end lines */
+	public static final String MULTI_COMMENT_END_PREFIX= " */"; //$NON-NLS-1$
+
+	/** Line prefix of multi-line comment content lines */
+	public static final String MULTI_COMMENT_START_PREFIX= "/* "; //$NON-NLS-1$
+
+	/** The indentation reference of this line */
+	private String fReferenceIndentation= ""; //$NON-NLS-1$
+	
+	/** The javadoc tag lookup. */
+	private static final Set fgTagLookup;
+	
+	static {
+		fgTagLookup= new HashSet();
+		for (int i= 0; i < JAVADOC_BREAK_TAGS.length; i++) {
+			fgTagLookup.add(JAVADOC_BREAK_TAGS[i]);
+		}
+		for (int i= 0; i < JAVADOC_SINGLE_BREAK_TAG.length; i++) {
+			fgTagLookup.add(JAVADOC_SINGLE_BREAK_TAG[i]);
+		}
+		for (int i= 0; i < JAVADOC_CODE_TAGS.length; i++) {
+			fgTagLookup.add(JAVADOC_CODE_TAGS[i]);
+		}
+		for (int i= 0; i < JAVADOC_IMMUTABLE_TAGS.length; i++) {
+			fgTagLookup.add(JAVADOC_IMMUTABLE_TAGS[i]);
+		}
+		for (int i= 0; i < JAVADOC_NEWLINE_TAGS.length; i++) {
+			fgTagLookup.add(JAVADOC_NEWLINE_TAGS[i]);
+		}
+		for (int i= 0; i < JAVADOC_SEPARATOR_TAGS.length; i++) {
+			fgTagLookup.add(JAVADOC_SEPARATOR_TAGS[i]);
+		}
+	}
+
+	/**
+	 * Creates a new multi-line comment line.
+	 * 
+	 * @param region comment region to create the line for
+	 */
+	protected MultiCommentLine(final CommentRegion region) {
+		super(region);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#adapt(org.eclipse.jdt.internal.corext.text.comment.CommentLine)
+	 */
+	protected void adapt(final CommentLine previous) {
+
+		if (!hasAttribute(COMMENT_ROOT) && !hasAttribute(COMMENT_PARAMETER) && !previous.hasAttribute(COMMENT_BLANKLINE))
+			fReferenceIndentation= previous.getIndentationReference();
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#append(org.eclipse.jdt.internal.corext.text.comment.CommentRange)
+	 */
+	protected void append(final CommentRange range) {
+
+		final MultiCommentRegion parent= (MultiCommentRegion)getParent();
+
+		if (range.hasAttribute(COMMENT_PARAMETER))
+			setAttribute(COMMENT_PARAMETER);
+		else if (range.hasAttribute(COMMENT_ROOT))
+			setAttribute(COMMENT_ROOT);
+		else if (range.hasAttribute(COMMENT_BLANKLINE))
+			setAttribute(COMMENT_BLANKLINE);
+
+		final int ranges= getSize();
+		if (ranges == 1) {
+
+			if (parent.isIndentRoots()) {
+
+				final CommentRange first= getFirst();
+				final String common= parent.getText(first.getOffset(), first.getLength()) + CommentRegion.COMMENT_RANGE_DELIMITER;
+
+				if (hasAttribute(COMMENT_ROOT))
+					fReferenceIndentation= common;
+				else if (hasAttribute(COMMENT_PARAMETER)) {
+					if (parent.isIndentDescriptions())
+						fReferenceIndentation= "\t" + common; //$NON-NLS-1$
+					else
+						fReferenceIndentation= common;
+				}
+			}
+		}
+		super.append(range);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getContentLinePrefix()
+	 */
+	protected String getContentPrefix() {
+		return MULTI_COMMENT_CONTENT_PREFIX;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getEndLinePrefix()
+	 */
+	protected String getEndingPrefix() {
+		return MULTI_COMMENT_END_PREFIX;
+	}
+
+	/**
+	 * Returns the reference indentation to use for this line.
+	 * 
+	 * @return the reference indentation for this line
+	 */
+	protected final String getIndentationReference() {
+		return fReferenceIndentation;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getStartLinePrefix()
+	 */
+	protected String getStartingPrefix() {
+		return MULTI_COMMENT_START_PREFIX;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#scanLine(int)
+	 */
+	protected void scanLine(final int line) {
+
+		final CommentRegion parent= getParent();
+		final String start= getStartingPrefix().trim();
+		final String end= getEndingPrefix().trim();
+		final String content= getContentPrefix().trim();
+
+		final int lines= parent.getSize();
+		final CommentRange range= getFirst();
+
+		int offset= 0;
+		int postfix= 0;
+
+		String text= parent.getText(range.getOffset(), range.getLength());
+		if (line == 0) {
+
+			offset= text.indexOf(start);
+			if (offset >= 0 && text.substring(0, offset).trim().length() != 0)
+				offset= -1;
+			
+			if (offset >= 0) {
+
+				offset += start.length();
+				range.trimBegin(offset);
+
+				postfix= text.lastIndexOf(end);
+				if (postfix >= 0 && text.substring(postfix + end.length()).trim().length() != 0)
+					postfix= -1;
+				
+				if (postfix >= offset)
+					// comment ends on same line
+					range.setLength(postfix - offset);
+				else {
+					postfix= text.lastIndexOf(content);
+					if (postfix >= 0 && text.substring(postfix + content.length()).trim().length() != 0)
+						postfix= -1;
+					
+					if (postfix >= offset) {
+
+						range.setLength(postfix - offset);
+						parent.setBorder(BORDER_UPPER);
+
+						if (postfix > offset) {
+
+							text= parent.getText(range.getOffset(), range.getLength());
+							final IRegion region= trimLine(text, content);
+
+							range.move(region.getOffset());
+							range.setLength(region.getLength());
+						}
+					}
+				}
+			}
+		} else if (line == lines - 1) {
+
+			offset= text.indexOf(content);
+			if (offset >= 0 && text.substring(0, offset).trim().length() != 0)
+				offset= -1;
+			postfix= text.lastIndexOf(end);
+			if (postfix >= 0 && text.substring(postfix + end.length()).trim().length() != 0)
+				postfix= -1;
+			
+			if (offset >= 0 && offset == postfix)
+				// no content on line, only the comment postfix
+				range.setLength(0);
+			else {
+				if (offset >= 0)
+					// omit the content prefix
+					range.trimBegin(offset + content.length());
+				
+				if (postfix >= 0)
+					// omit the comment postfix
+					range.trimEnd(-end.length());
+				
+				text= parent.getText(range.getOffset(), range.getLength());
+				final IRegion region= trimLine(text, content);
+				if (region.getOffset() != 0 || region.getLength() != text.length()) {
+
+					range.move(region.getOffset());
+					range.setLength(region.getLength());
+
+					parent.setBorder(BORDER_UPPER);
+					parent.setBorder(BORDER_LOWER);
+				}
+			}
+		} else {
+
+			offset= text.indexOf(content);
+			if (offset >= 0 && text.substring(0, offset).trim().length() != 0)
+				offset= -1;
+			
+			if (offset >= 0) {
+
+				offset += content.length();
+				range.trimBegin(offset);
+			}
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#tokenizeLine(int)
+	 */
+	protected void tokenizeLine(int line) {
+
+		int offset= 0;
+		int index= offset;
+
+		final CommentRegion parent= getParent();
+		final CommentRange range= getFirst();
+		final int begin= range.getOffset();
+
+		final String content= parent.getText(begin, range.getLength());
+		final int length= content.length();
+
+		while (offset < length && Character.isWhitespace(content.charAt(offset)))
+			offset++;
+
+		CommentRange result= null;
+		if (offset >= length && !parent.isClearLines() && (line > 0 && line < parent.getSize() - 1)) {
+
+			result= new CommentRange(begin, 0);
+			result.setAttribute(COMMENT_BLANKLINE);
+			result.setAttribute(COMMENT_FIRST_TOKEN);
+
+			parent.append(result);
+		}
+
+		int attribute= COMMENT_FIRST_TOKEN | COMMENT_STARTS_WITH_RANGE_DELIMITER;
+		while (offset < length) {
+
+			while (offset < length && Character.isWhitespace(content.charAt(offset))) {
+				offset++;
+				attribute |= COMMENT_STARTS_WITH_RANGE_DELIMITER;
+			}
+
+			index= offset;
+
+			if (index < length) {
+
+				if (content.charAt(index) == HTML_TAG_PREFIX) {
+
+					// in order to avoid recognizing any < in a comment, even those which are part of e.g.
+					// java source code, we validate the tag content to be one of the recognized
+					// tags (structural, breaks, pre, code).
+					int tag= ++index;
+					while (index < length && content.charAt(index) != HTML_TAG_POSTFIX && content.charAt(index) != HTML_TAG_PREFIX)
+						index++;
+
+					if (index < length && content.charAt(index) == HTML_TAG_POSTFIX && isValidTag(content.substring(tag, index))) {
+						index++;
+						attribute |= COMMENT_HTML; // only set html attribute if postfix found
+					} else {
+						// no tag - do the usual thing from the original offset
+						index= tag;
+						while (index < length && !Character.isWhitespace(content.charAt(index)) && content.charAt(index) != HTML_TAG_PREFIX && !content.startsWith(LINK_TAG_PREFIX, index))
+							index++;
+					}
+
+
+				} else if (content.startsWith(LINK_TAG_PREFIX, index)) {
+
+					while (index < length && content.charAt(index) != LINK_TAG_POSTFIX)
+						index++;
+
+					if (index < length && content.charAt(index) == LINK_TAG_POSTFIX)
+						index++;
+
+					attribute |= COMMENT_OPEN | COMMENT_CLOSE;
+
+				} else {
+
+					while (index < length && !Character.isWhitespace(content.charAt(index)) && content.charAt(index) != HTML_TAG_PREFIX && !content.startsWith(LINK_TAG_PREFIX, index))
+						index++;
+				}
+			}
+
+			if (index - offset > 0) {
+
+				result= new CommentRange(begin + offset, index - offset);
+				result.setAttribute(attribute);
+
+				parent.append(result);
+				offset= index;
+			}
+			
+			attribute= 0;
+		}
+	}
+
+	/**
+	 * Checks whether <code>tag</code> is a valid tag content (text inside
+	 * the angular brackets &lt;, &gt;).
+	 * <p>
+	 * The algorithm is to see if the tag trimmed of whitespace and an
+	 * optional slash starts with one of our recognized tags.
+	 * 
+	 * @param tag the tag to check
+	 * @return <code>true</code> if <code>tag</code> is a valid tag
+	 *         content
+	 */
+	private boolean isValidTag(String tag) {
+		// strip the slash
+		if (tag.startsWith("/")) //$NON-NLS-1$
+			tag= tag.substring(1, tag.length());
+		
+		// strip ws
+		tag= tag.trim();
+		
+		// extract first token
+		int i= 0;
+		while (i < tag.length() && !Character.isWhitespace(tag.charAt(i)))
+			i++;
+		tag= tag.substring(0, i);
+		
+		// see if it's a tag
+		return isTagName(tag.toLowerCase());
+	}
+
+	/**
+	 * Checks whether <code>tag</code> is one of the configured tags.
+	 * 
+	 * @param tag the tag to check
+	 * @return <code>true</code> if <code>tag</code> is a configured tag
+	 *         name
+	 */
+	private boolean isTagName(String tag) {
+		return fgTagLookup.contains(tag);
+	}
+
+	/**
+	 * Removes all leading and trailing occurrences from <code>line</code>.
+	 * 
+	 * @param line the string to remove the occurrences of
+	 *                <code>trimmable</code>
+	 * @param trimmable the string to remove from <code>line</code>
+	 * @return the region of the trimmed substring within <code>line</code>
+	 */
+	protected final IRegion trimLine(final String line, final String trimmable) {
+
+		final int trim= trimmable.length();
+
+		int offset= 0;
+		int length= line.length() - trim;
+
+		while (line.startsWith(trimmable, offset))
+			offset += trim;
+
+		while (line.startsWith(trimmable, length))
+			length -= trim;
+
+		return new Region(offset, length + trim);
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentRegion.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentRegion.java
new file mode 100644
index 0000000..680a372
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/MultiCommentRegion.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+import java.util.Iterator;
+import java.util.ListIterator;
+
+import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+
+/**
+ * Multi-comment region in a source code document.
+ * 
+ * @since 3.0
+ */
+public class MultiCommentRegion extends CommentRegion implements IJavaDocTagConstants {
+
+	/** Should root tag parameter descriptions be indented after the tag? */
+	private final boolean fIndentDescriptions;
+
+	/** Should root tag parameter descriptions be indented? */
+	private final boolean fIndentRoots;
+
+	/** Should description of parameters go to the next line? */
+	private final boolean fParameterNewLine;
+
+	/** Should root tags be separated from description? */
+	private boolean fSeparateRoots;
+
+ 	/**
+	 * Creates a new multi-comment region.
+	 * 
+	 * @param document the document which contains the comment region
+	 * @param position the position of this comment region in the document
+	 * @param formatter the given formatter
+	 */
+	public MultiCommentRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
+		super(document, position, formatter);
+
+		fIndentRoots= this.preferences.comment_indent_root_tags;
+		fIndentDescriptions= this.preferences.comment_indent_parameter_description;
+		fSeparateRoots= this.preferences.comment_insert_empty_line_before_root_tags;
+		fParameterNewLine= this.preferences.comment_insert_new_line_for_parameter;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canAppend(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, int, int)
+	 */
+	protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, int count) {
+
+		final boolean blank= next.hasAttribute(COMMENT_BLANKLINE);
+
+		// Avoid wrapping punctuation
+		if (next.getLength() <= 2 && !blank && isNonAlphaNumeric(next))
+			return true;
+
+		if (fParameterNewLine && line.hasAttribute(COMMENT_PARAMETER) && line.getSize() > 1)
+			return false;
+
+		if (previous != null) {
+			
+			if (index != 0 && (blank || previous.hasAttribute(COMMENT_BLANKLINE) || next.hasAttribute(COMMENT_PARAMETER) || next.hasAttribute(COMMENT_ROOT) || next.hasAttribute(COMMENT_SEPARATOR) || next.hasAttribute(COMMENT_NEWLINE) || previous.hasAttribute(COMMENT_BREAK) || previous.hasAttribute(COMMENT_SEPARATOR)))
+				return false;
+			
+			if (previous.hasAttribute(COMMENT_ROOT))
+				return true;
+
+			if (next.hasAttribute(COMMENT_IMMUTABLE) && previous.hasAttribute(COMMENT_IMMUTABLE))
+				return true;
+		}
+
+		// always append elements that did not have any range separators
+		if (!next.hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER)) {
+			return true;
+		}
+
+		if (fIndentRoots && !line.hasAttribute(COMMENT_ROOT) && !line.hasAttribute(COMMENT_PARAMETER))
+			count -= stringToLength(line.getIndentationReference());
+
+		// Avoid appending consecutive immutable ranges, which together exceed the line width
+		if (next.hasAttribute(COMMENT_IMMUTABLE) && (previous == null || !previous.hasAttribute(COMMENT_IMMUTABLE))) {
+			// Breaking the abstraction by directly accessing the list of ranges for looking ahead
+			Iterator iter= getRanges().iterator();
+			CommentRange current= null;
+			while (iter.hasNext() && current != next)
+				current= (CommentRange) iter.next();
+			
+			if (current != null && iter.hasNext()) {
+				try {
+					int lineNumber= getDocument().getLineOfOffset(getOffset() + current.getOffset());
+					CommentRange last= current;
+					while (iter.hasNext()) {
+						current= (CommentRange) iter.next();
+						if (current.hasAttribute(COMMENT_IMMUTABLE) && getDocument().getLineOfOffset(getOffset() + current.getOffset()) == lineNumber)
+							last= current;
+						else
+							break;
+					}
+					count -= last.getOffset() + last.getLength() - (next.getOffset() + next.getLength());
+				} catch (BadLocationException e) {
+					// Should not happen
+				}
+			}
+		}
+
+		return super.canAppend(line, previous, next, index, count);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#getDelimiter(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
+	 */
+	protected String getDelimiter(CommentLine predecessor, CommentLine successor, CommentRange previous, CommentRange next, String indentation) {
+
+		final String delimiter= super.getDelimiter(predecessor, successor, previous, next, indentation);
+
+		if (previous != null) {
+
+			// Blank line before <pre> tag
+			if (previous.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !next.hasAttribute(COMMENT_CODE) && !successor.hasAttribute(COMMENT_BLANKLINE))
+				return delimiter + delimiter;
+
+			// Blank line after </pre> tag
+			else if (next.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
+				return delimiter + delimiter;
+
+			// Add blank line before first root/parameter tag, if "Blank line before Javadoc tags"
+			else if (fSeparateRoots && previous.hasAttribute(COMMENT_PARAGRAPH) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
+				return delimiter + delimiter;
+
+			else if (fIndentRoots && !predecessor.hasAttribute(COMMENT_ROOT) && !predecessor.hasAttribute(COMMENT_PARAMETER) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
+				return delimiter + stringToIndent(predecessor.getIndentationReference(), false);
+		}
+		return delimiter;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#getDelimiter(org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange)
+	 */
+	protected String getDelimiter(final CommentRange previous, final CommentRange next) {
+		// simply preserve range (~ word) breaks
+		if (previous != null && !previous.hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER)) {
+			return ""; //$NON-NLS-1$
+		} else {
+			return super.getDelimiter(previous, next);
+		}
+	}
+
+	/**
+	 * Should root tag parameter descriptions be indented after the tag?
+	 * 
+	 * @return <code>true</code> iff the descriptions should be indented
+	 *         after, <code>false</code> otherwise.
+	 */
+	protected final boolean isIndentDescriptions() {
+		return fIndentDescriptions;
+	}
+
+	/**
+	 * Should root tag parameter descriptions be indented?
+	 * 
+	 * @return <code>true</code> iff the root tags should be indented,
+	 *         <code>false</code> otherwise.
+	 */
+	protected final boolean isIndentRoots() {
+		return fIndentRoots;
+	}
+
+	/**
+	 * Marks the comment ranges confined by HTML ranges.
+	 */
+	protected void markHtmlRanges() {
+		// Do nothing
+	}
+
+	/**
+	 * Marks the comment range with its HTML tag attributes.
+	 * 
+	 * @param range the comment range to mark
+	 * @param token token associated with the comment range
+	 */
+	protected void markHtmlTag(final CommentRange range, final String token) {
+		// Do nothing
+	}
+
+	/**
+	 * Marks the comment range with its javadoc tag attributes.
+	 * 
+	 * @param range the comment range to mark
+	 * @param token token associated with the comment range
+	 */
+	protected void markJavadocTag(final CommentRange range, final String token) {
+		range.markPrefixTag(COMMENT_ROOT_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_ROOT);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#markRegion()
+	 */
+	protected void markRegion() {
+
+		int count= 0;
+		boolean paragraph= false;
+
+		String token= null;
+		CommentRange range= null;
+
+		for (final ListIterator iterator= getRanges().listIterator(); iterator.hasNext();) {
+
+			range= (CommentRange)iterator.next();
+			count= range.getLength();
+
+			if (count > 0) {
+
+				token= getText(range.getOffset(), count).toLowerCase();
+
+				markJavadocTag(range, token);
+				if (!paragraph && (range.hasAttribute(COMMENT_ROOT) || range.hasAttribute(COMMENT_PARAMETER))) {
+					range.setAttribute(COMMENT_PARAGRAPH);
+					paragraph= true;
+				}
+				markHtmlTag(range, token);
+			}
+		}
+		markHtmlRanges();
+	}
+	
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#createLine()
+	 * @since 3.1
+	 */
+	protected CommentLine createLine() {
+		return new MultiCommentLine(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SingleCommentLine.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SingleCommentLine.java
new file mode 100644
index 0000000..f7dc838
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SingleCommentLine.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+/**
+ * Single-line comment line in a comment region.
+ * 
+ * @since 3.0
+ */
+public class SingleCommentLine extends CommentLine {
+
+	/** Line prefix for single line comments */
+	public static final String SINGLE_COMMENT_PREFIX= "// "; //$NON-NLS-1$
+
+	/** NLS tag prefix */
+	private static final String NLS_TAG_PREFIX= "//$NON-NLS-"; //$NON-NLS-1$
+	
+	/** Is the comment a NLS locale tag sequence? */
+	private boolean fLocaleSequence= false;
+
+	/**
+	 * Creates a new single-line comment line.
+	 * 
+	 * @param region comment region to create the line for
+	 */
+	protected SingleCommentLine(final CommentRegion region) {
+		super(region);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#adapt(org.eclipse.jdt.internal.corext.text.comment.CommentLine)
+	 */
+	protected void adapt(final CommentLine previous) {
+		// Do nothing
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#formatLowerBorder(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String, int)
+	 */
+	protected void formatLowerBorder(final CommentRange range, final String indentation, final int length) {
+
+		final int offset= range.getOffset() + range.getLength();
+		final CommentRegion parent= getParent();
+
+		parent.logEdit(parent.getDelimiter(), offset, parent.getLength() - offset);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#formatUpperBorder(org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String, int)
+	 */
+	protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) {
+
+		final CommentRegion parent= getParent();
+
+		parent.logEdit(getContentPrefix(), 0, range.getOffset());
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getContentPrefix()
+	 */
+	protected String getContentPrefix() {
+		return SINGLE_COMMENT_PREFIX;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getEndingPrefix()
+	 */
+	protected String getEndingPrefix() {
+		return SINGLE_COMMENT_PREFIX;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#getStartingPrefix()
+	 */
+	protected String getStartingPrefix() {
+		return SINGLE_COMMENT_PREFIX;
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#scanLine(int)
+	 */
+	protected void scanLine(final int line) {
+
+		final CommentRange range= getFirst();
+		final String content= getParent().getText(range.getOffset(), range.getLength());
+		final String prefix= getContentPrefix().trim();
+
+		final int offset= content.indexOf(prefix);
+		if (offset >= 0) {
+
+			if (content.startsWith(NLS_TAG_PREFIX))
+				fLocaleSequence= true;
+
+			range.trimBegin(offset + prefix.length());
+		}
+	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.corext.text.comment.CommentLine#tokenizeLine(int)
+	 */
+	protected void tokenizeLine(final int line) {
+
+		if (!fLocaleSequence)
+			super.tokenizeLine(line);
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SubstitutionTextReader.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SubstitutionTextReader.java
new file mode 100644
index 0000000..14dc788
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/SubstitutionTextReader.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.formatter.comment;
+
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * Reads the text contents from a reader and computes for each character
+ * a potential substitution. The substitution may eat more characters than 
+ * only the one passed into the computation routine.
+ */
+public abstract class SubstitutionTextReader extends Reader {
+	
+	private Reader fReader;
+	private boolean fWasWhiteSpace;
+	private int fCharAfterWhiteSpace;
+
+	/**
+	 * Tells whether white space characters are skipped.
+	 */
+	private boolean fSkipWhiteSpace= true;
+	
+	private boolean fReadFromBuffer;
+	private StringBuffer fBuffer;
+	private int fIndex;
+
+
+	protected SubstitutionTextReader(Reader reader) {
+		fReader= reader;
+		fBuffer= new StringBuffer();
+		fIndex= 0;
+		fReadFromBuffer= false;
+		fCharAfterWhiteSpace= -1;
+		fWasWhiteSpace= true;
+	}
+	
+	/**
+	 * Gets the content as a String
+	 */
+	public String getString() throws IOException {
+		StringBuffer buf= new StringBuffer();
+		int ch;
+		while ((ch= read()) != -1) {
+			buf.append((char)ch);
+		}
+		return buf.toString();
+	}
+	
+	/**
+	 * Implement to compute the substitution for the given character and 
+	 * if necessary subsequent characters. Use <code>nextChar</code>
+	 * to read subsequent characters.
+	 */
+	protected abstract String computeSubstitution(int c) throws IOException;
+	
+	/**
+	 * Returns the internal reader.
+	 */
+	protected Reader getReader() {
+		return fReader;
+	}
+	 
+	/**
+	 * Returns the next character.
+	 */
+	protected int nextChar() throws IOException {
+		fReadFromBuffer= (fBuffer.length() > 0);
+		if (fReadFromBuffer) {
+			char ch= fBuffer.charAt(fIndex++);
+			if (fIndex >= fBuffer.length()) {
+				fBuffer.setLength(0);
+				fIndex= 0;
+			}
+			return ch;
+		} else {
+			int ch= fCharAfterWhiteSpace;
+			if (ch == -1) {
+				ch= fReader.read();
+			}
+			if (fSkipWhiteSpace && Character.isWhitespace((char)ch)) {
+				do {
+					ch= fReader.read();
+				} while (Character.isWhitespace((char)ch));
+				if (ch != -1) {
+					fCharAfterWhiteSpace= ch;
+					return ' ';
+				}
+			} else {
+				fCharAfterWhiteSpace= -1;
+			}
+			return ch;
+		}
+	}
+	
+	/*
+	 * @see Reader#read()
+	 */
+	public int read() throws IOException {
+		int c;
+		do {
+			
+			c= nextChar();
+			while (!fReadFromBuffer) {
+				String s= computeSubstitution(c);
+				if (s == null)
+					break;
+				if (s.length() > 0)
+					fBuffer.insert(0, s);
+				c= nextChar();
+			}
+			
+		} while (fSkipWhiteSpace && fWasWhiteSpace && (c == ' '));
+		fWasWhiteSpace= (c == ' ' || c == '\r' || c == '\n');
+		return c;
+	}
+		
+	/*
+	 * @see Reader#read(char[],int,int)
+	 */
+	public int read(char cbuf[], int off, int len) throws IOException {
+		int end= off + len;
+		for (int i= off; i < end; i++) {
+			int ch= read();
+			if (ch == -1) {
+				if (i == off) {
+					return -1;
+				} else {
+					return i - off;
+				}
+			}
+			cbuf[i]= (char)ch;
+		}
+		return len;
+	}		
+	
+	/*
+	 * @see java.io.Reader#ready()
+	 */
+	public boolean ready() throws IOException {
+		return fReader.ready();
+	}
+		
+	/*
+	 * @see Reader#close()
+	 */		
+	public void close() throws IOException {
+		fReader.close();
+	}
+	
+	/*
+	 * @see Reader#reset()
+	 */		
+	public void reset() throws IOException {
+		fReader.reset();
+		fWasWhiteSpace= true;
+		fCharAfterWhiteSpace= -1;
+		fBuffer.setLength(0);
+		fIndex= 0;		
+	}
+
+	protected final void setSkipWhitespace(boolean state) {
+		fSkipWhiteSpace= state;
+	}
+
+	protected final boolean isSkippingWhitespace() {
+		return fSkipWhiteSpace;
+	}
+}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/package.html b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/package.html
new file mode 100644
index 0000000..d2210a7
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/comment/package.html
@@ -0,0 +1,46 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="IBM">
+   <title>Package-level Javadoc</title>
+</head>
+<body>
+Provides facilities to format comments in Java source code.
+<h2>
+Package Specification</h2>
+This package provides interfaces and implementations for three kinds of comment types used in 
+Java source code:
+<ul>
+<li>Javadoc comments</li>
+<li>Multi-line comments</li>
+<li>Single-line comments</li>
+</ul>
+<h3>
+Comment Formatting</h3>
+Comment regions form the principle access point to the formatting of comments. To create a comment 
+region for a specified comment type, the factory method 
+<tt>CommentObjectFactory#createRegion(IDocument, TypedPosition, String, Map, StyledText)</tt> 
+should be used.<p>
+The formatting process is then launch by calling <tt>CommentRegion#format(String)</tt>, where 
+the argument denotes the desired indentation. This method returns a textedit representing the changes that where made during 
+the formatting process. The document for which the comment region was created is therefore guaranteed 
+to remain unchanged.<p>
+Internally, the comment region is first cast into comment lines to form the basis of the following scan step: 
+Each comment line is scanned for valid prefixes and tokenized afterwards. This tokenize step yields a stream of 
+tokens called comment ranges that are then marked with attributes representing information about the kind of 
+token associated with that comment range.<p>
+Once the comment ranges have enough attributed information, the comment region wraps the comment ranges at 
+the line margin boundary. This is coordinated by a set of rules that can be contributed to a certain type of comment 
+region. At this point of time, the comment range stream already represents the formatted comment region. The last 
+step therefore is to record the edits and to construct the resulting text edit, which describes all the changes that were 
+made to the comment region.
+<br>
+Note that the changes are not directly applied to the document. Clients are responsible for applying the textedit 
+and updating and preserving the document structure.
+<p>
+All the objects used during comment formatting should not directly be instantiated, but 
+rather retrieved from the factory <tt>CommentObjectFactory</tt>. This factory ensures 
+that the right kind of regions and lines are returned for a specific comment type.
+</body>
+</html>
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
index 7b7be0c..ba7299c 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties
index 1265f46..db13f9e 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/options.properties
@@ -1,10 +1,10 @@
 ###############################################################################
 # Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
@@ -72,4 +72,4 @@
 space.castexpression.category=Style
 space.castexpression.name=&Insert a space in cast expression
 space.castexpression.size.possibleValues=2|Insert|Do not insert
-space.castexpression.description=When insert, a space is added between the closing parenthesis and the expression of the cast expression
\ No newline at end of file
+space.castexpression.description=When insert, a space is added between the closing parenthesis and the expression of the cast expression
diff --git a/org.eclipse.jdt.core/grammar/java_1_5.g b/org.eclipse.jdt.core/grammar/java_1_5.g
index a0f100c..375240b 100644
--- a/org.eclipse.jdt.core/grammar/java_1_5.g
+++ b/org.eclipse.jdt.core/grammar/java_1_5.g
@@ -39,8 +39,8 @@
 	Identifier

 

 	abstract assert boolean break byte case catch char class 

-	continue default do double else enum extends false final finally float

-	for if implements import instanceof int

+	continue const default do double else enum extends false final finally float

+	for goto if implements import instanceof int

 	interface long native new null package private

 	protected public return short static strictfp super switch

 	synchronized this throw throws transient true try void

@@ -367,10 +367,14 @@
 /:$readableName PackageDeclarationName:/

 /:$compliance 1.5:/

 

-PackageDeclarationName ::= 'package' Name

+PackageDeclarationName ::= PackageComment 'package' Name

 /.$putCase  consumePackageDeclarationName(); $break ./

 /:$readableName PackageDeclarationName:/

 

+PackageComment ::= $empty

+/.$putCase  consumePackageComment(); $break ./

+/:$readableName PackageComment:/

+

 ImportDeclaration -> SingleTypeImportDeclaration

 ImportDeclaration -> TypeImportOnDemandDeclaration

 -----------------------------------------------

@@ -753,10 +757,6 @@
 /.$putCase consumeInterfaceHeaderName1(); $break ./

 /:$readableName InterfaceHeaderName:/

 

--- This rule will be used to accept inner local interface and then report a relevant error message

-InvalidInterfaceDeclaration -> InterfaceHeader InterfaceBody

-/:$readableName InvalidInterfaceDeclaration:/

-

 InterfaceHeaderExtends ::= 'extends' InterfaceTypeList

 /.$putCase consumeInterfaceHeaderExtends(); $break ./

 /:$readableName InterfaceHeaderExtends:/

@@ -774,20 +774,16 @@
 /.$putCase consumeEmptyInterfaceMemberDeclaration(); $break ./

 /:$readableName InterfaceMemberDeclaration:/

 

--- This rule is added to be able to parse non abstract method inside interface and then report a relevent error message

-InvalidMethodDeclaration -> MethodHeader MethodBody

-/:$readableName InvalidMethodDeclaration:/

-

 InterfaceMemberDeclaration -> ConstantDeclaration

-InterfaceMemberDeclaration ::= InvalidMethodDeclaration

-/.$putCase ignoreMethodBody(); $break ./

+InterfaceMemberDeclaration ::= MethodHeader MethodBody

+/.$putCase consumeInvalidMethodDeclaration(); $break ./

 /:$readableName InterfaceMemberDeclaration:/

 

 -- These rules are added to be able to parse constructors inside interface and then report a relevent error message

 InvalidConstructorDeclaration ::= ConstructorHeader MethodBody

-/.$putCase ignoreInvalidConstructorDeclaration(true);  $break ./

+/.$putCase consumeInvalidConstructorDeclaration(true);  $break ./

 InvalidConstructorDeclaration ::= ConstructorHeader ';'

-/.$putCase ignoreInvalidConstructorDeclaration(false);  $break ./

+/.$putCase consumeInvalidConstructorDeclaration(false);  $break ./

 /:$readableName InvalidConstructorDeclaration:/

 

 InterfaceMemberDeclaration -> AbstractMethodDeclaration

@@ -837,8 +833,14 @@
 BlockStatement -> Statement

 --1.1 feature

 BlockStatement -> ClassDeclaration

-BlockStatement ::= InvalidInterfaceDeclaration

-/.$putCase ignoreInterfaceDeclaration(); $break ./

+BlockStatement ::= InterfaceDeclaration

+/.$putCase consumeInvalidInterfaceDeclaration(); $break ./

+/:$readableName BlockStatement:/

+BlockStatement ::= AnnotationTypeDeclaration

+/.$putCase consumeInvalidAnnotationTypeDeclaration(); $break ./

+/:$readableName BlockStatement:/

+BlockStatement ::= EnumDeclaration

+/.$putCase consumeInvalidEnumDeclaration(); $break ./

 /:$readableName BlockStatement:/

 

 LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';'

@@ -1145,18 +1147,18 @@
 /.$putCase consumeClassInstanceCreationExpression(); $break ./

 --1.1 feature

 

-ClassInstanceCreationExpression ::= Primary '.' 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' ClassBodySimpleNameopt

+ClassInstanceCreationExpression ::= Primary '.' 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt

 /.$putCase consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; $break ./

 

-ClassInstanceCreationExpression ::= Primary '.' 'new' ClassType '(' ArgumentListopt ')' ClassBodySimpleNameopt

+ClassInstanceCreationExpression ::= Primary '.' 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt

 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./

 

 --1.1 feature

-ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' ClassType '(' ArgumentListopt ')' ClassBodySimpleNameopt

+ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt

 /.$putCase consumeClassInstanceCreationExpressionQualified() ; $break ./

 /:$readableName ClassInstanceCreationExpression:/

 

-ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' ClassBodySimpleNameopt

+ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' OnlyTypeArguments ClassType '(' ArgumentListopt ')' ClassBodyopt

 /.$putCase consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; $break ./

 /:$readableName ClassInstanceCreationExpression:/

 

@@ -1169,15 +1171,6 @@
 ClassBodyopt ::= EnterAnonymousClassBody ClassBody

 /:$readableName ClassBody:/

 

-ClassBodySimpleNameopt ::= $empty --test made using null as contents

-/.$putCase consumeClassBodyopt(); $break ./

-ClassBodySimpleNameopt ::= EnterAnonymousClassBodySimpleName ClassBody

-/:$readableName ClassBody:/

-

-EnterAnonymousClassBodySimpleName ::= $empty

-/.$putCase consumeEnterAnonymousClassBodySimpleName(); $break ./

-/:$readableName EnterAnonymousClassBodySimpleName:/

-

 EnterAnonymousClassBody ::= $empty

 /.$putCase consumeEnterAnonymousClassBody(); $break ./

 /:$readableName EnterAnonymousClassBody:/

@@ -2135,11 +2128,21 @@
 /:$readableName MemberValuePairs:/

 /:$compliance 1.5:/

 

-MemberValuePair ::= SimpleName '=' MemberValue

+MemberValuePair ::= SimpleName '=' EnterMemberValue MemberValue ExitMemberValue

 /.$putCase consumeMemberValuePair() ; $break ./

 /:$readableName MemberValuePair:/

 /:$compliance 1.5:/

 

+EnterMemberValue ::= $empty

+/.$putCase consumeEnterMemberValue() ; $break ./

+/:$readableName EnterMemberValue:/

+/:$compliance 1.5:/

+

+ExitMemberValue ::= $empty

+/.$putCase consumeExitMemberValue() ; $break ./

+/:$readableName ExitMemberValue:/

+/:$compliance 1.5:/

+

 MemberValue -> ConditionalExpression_NotName

 /:$compliance 1.5:/

 MemberValue ::= Name

diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
new file mode 100644
index 0000000..1c7c5d2
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BindingKey.java
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.internal.core.util.KeyKind;
+import org.eclipse.jdt.internal.core.util.KeyToSignature;
+
+/**
+ * Utility class to decode or create a binding key.
+ * <p>
+ * This class is not intended to be subclassed by clients.
+ * </p>
+ * 
+ * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+ * @since 3.1
+ */
+public final class BindingKey {
+	
+	private String key;
+	
+	/**
+	 * Creates a new binding key.
+	 * 
+	 * @param key the key to decode
+	 */
+	public BindingKey(String key) {
+		this.key = key;
+	}
+	
+	/**
+	 * Creates a new array type binding key from the given type binding key and the given array dimension.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createArrayTypeBindingKey("Ljava/lang/Object;", 1) -> "[Ljava/lang/Object;"
+	 * createArrayTypeBindingKey("I", 2) -> "[[I"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeKey the binding key of the given type
+	 * @param arrayDimension the given array dimension
+	 * @return a new array type binding key
+	 */
+	public static String createArrayTypeBindingKey(String typeKey, int arrayDimension) {
+		// Note this implementation is heavily dependent on ArrayTypeBinding#computeUniqueKey() 
+		StringBuffer buffer = new StringBuffer();
+		while (arrayDimension-- > 0)
+			buffer.append('[');
+		buffer.append(typeKey);
+		return buffer.toString();
+	}
+	
+	/**
+	 * Creates a new parameterized type binding key from the given generic type binding key and the given argument type binding keys.
+	 * If the argument type keys array is empty, then a raw type binding key is created.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createParameterizedTypeBindingKey("Ljava/util/Map<TK;TV;>;", new String[] {"Ljava/lang/String;", "Ljava/lang/Object;"}) -> "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;"
+	 * createParameterizedTypeBindingKey("Ljava/util/List<TE;>;", new String[] {}) -> "Ljava/util/List<>;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param genericTypeKey the binding key of the generic type
+	 * @param argumentTypeKeys the possibly empty list of binding keys of argument types
+	 * @return a new parameterized type binding key
+	 */
+	public static String createParameterizedTypeBindingKey(String genericTypeKey, String[] argumentTypeKeys) {
+		// Note this implementation is heavily dependent on ParameterizedTypeBinding#computeUniqueKey() and its subclasses
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(Signature.getTypeErasure(genericTypeKey));
+		buffer.insert(buffer.length()-1, '<');
+		for (int i = 0, length = argumentTypeKeys.length; i < length; i++) {
+			String argumentTypeKey = argumentTypeKeys[i];
+			buffer.insert(buffer.length()-1, argumentTypeKey);
+		}
+		buffer.insert(buffer.length()-1, '>');
+		return buffer.toString();
+	}
+	
+	/**
+	 * Creates a new type binding key from the given type name. The type name must be either 
+	 * a fully qualified name, an array type name or a primitive type name. 
+	 * If the type name is fully qualified, then it is expected to be dot-based. 
+	 * Note that inner types, generic types and parameterized types are not supported.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createTypeBindingKey("int") -> "I"
+	 * createTypeBindingKey("java.lang.String") -> "Ljava/lang/String;"
+	 * createTypeBindingKey("boolean[]") -> "[Z"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeName the possibly qualified type name
+	 * @return a new type binding key
+	 */
+	public static String createTypeBindingKey(String typeName) {
+		// Note this implementation is heavily dependent on TypeBinding#computeUniqueKey() and its subclasses
+		return Signature.createTypeSignature(typeName.replace('.', '/'), true/*resolved*/);
+	}
+	
+	/**
+	 * Creates a new type variable binding key from the given type variable name and the given declaring key.
+	 * The declaring key can either be a type binding key or a method binding key.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createTypeVariableBindingKey("T", "Ljava/util/List<TE;>;") -> "Ljava/util/List<TE;>;:TT;"
+	 * createTypeVariableBindingKey("SomeTypeVariable", "Lp/X;.foo()V") -> "Lp/X;.foo()V:TSomeTypeVariable;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeVariableName the name of the given type variable
+	 * @param declaringKey the binding key of the type or method the type variable belongs to
+	 * @return a new type variable binding key
+	 */
+	public static String createTypeVariableBindingKey(String typeVariableName, String declaringKey) {
+		// Note this implementation is heavily dependent on TypeVariableBinding#computeUniqueKey() 
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(declaringKey);
+		buffer.append(':');
+		buffer.append('T');
+		buffer.append(typeVariableName);
+		buffer.append(';');
+		return buffer.toString();
+	}
+	
+	/**
+	 * Creates a new wildcard type binding key from the given type binding key and the given wildcard kind
+	 * (one of {@link Signature#C_STAR}, {@link Signature#C_SUPER}, or {@link Signature#C_EXTENDS}.
+	 * If the wildcard is {@link Signature#C_STAR}, the given type binding key is ignored.
+	 * <p>
+	 * For example:
+	 * <pre>
+	 * <code>
+	 * createWilcardTypeBindingKey(null, Signature.C_STAR) -> "*"
+	 * createWilcardTypeBindingKey("Ljava/util/List<TE;>;", Signature.C_SUPER) -> "-Ljava/util/List<TE;>;"
+	 * createWilcardTypeBindingKey("Ljava/util/ArrayList;", Signature.C_EXTENDS) -> "+Ljava/util/ArrayList;"
+	 * </code>
+	 * </pre>
+	 * </p>
+	 *
+	 * @param typeKey the binding key of the given type
+	 * @param kind one of {@link Signature#C_STAR}, {@link Signature#C_SUPER}, or {@link Signature#C_EXTENDS}
+	 * @return a new wildcard type binding key
+	 */
+	public static String createWilcardTypeBindingKey(String typeKey, char kind) {
+		// Note this implementation is heavily dependent on WildcardBinding#computeUniqueKey() 
+		switch (kind) {
+			case Signature.C_STAR:
+				return "*"; //$NON-NLS-1$
+			case Signature.C_SUPER:
+				return '-' + typeKey;
+			case Signature.C_EXTENDS:
+				return '+' + typeKey;
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the declaring type signature of the element represented by this binding key.
+	 * Returns the signature of the element if it is a type.
+	 * 
+	 * @return the declaring type signature
+	 */
+	public String getDeclaringTypeSignature() {
+		KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.DECLARING_TYPE);
+		keyToSignature.parse();
+		return keyToSignature.signature.toString();
+	}
+	
+	/**
+	 * Returns the type argument signatures of the element represented by this binding key.
+	 * If this binding key doesn't represent a parameterized type or a parameterized method,
+	 * returns an empty array.
+	 * 
+	 * @return the type argument signatures 
+	 */
+	public String[] getTypeArguments() {
+		KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.TYPE_ARGUMENTS);
+		keyToSignature.parse();
+		return keyToSignature.getTypeArguments();
+	}
+	
+	/**
+	 * Returns whether this binding key represents a raw type.
+	 * 
+	 * @return whether this binding key represents a raw type
+	 */
+	public boolean isRawType() {
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		return (kind.flags & KeyKind.F_RAW_TYPE) != 0;
+	}
+	
+	/**
+	 * Returns whether this binding key represents a parameterized type, or if its declaring type is a parameterized type.
+	 * 
+	 * @return whether this binding key represents a parameterized type
+	 */
+	public boolean isParameterizedType() {
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		return (kind.flags & KeyKind.F_PARAMETERIZED_TYPE) != 0;
+	}
+	
+	/**
+	 * Returns whether this binding key represents a parameterized method, or if its declaring method is a parameterized method.
+	 * 
+	 * @return whether this binding key represents a parameterized method
+	 */
+	public boolean isParameterizedMethod() {
+		KeyKind kind = new KeyKind(this.key);
+		kind.parse();
+		return (kind.flags & KeyKind.F_PARAMETERIZED_METHOD) != 0;
+	}
+	
+	/**
+	 * Transforms this binding key into a signature.
+	 * 
+	 * @return the signature for this binding key
+	 */
+	public String toSignature() {
+		KeyToSignature keyToSignature = new KeyToSignature(this.key, KeyToSignature.SIGNATURE);
+		keyToSignature.parse();
+		return keyToSignature.signature.toString();
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.key;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java
index a8a7fc7..b03507c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/BufferChangedEvent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java
index 39e4e96..578a8a2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathContainerInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added support for requesting updates of a particular
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java
index 96d346d..49d21b4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ClasspathVariableInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
new file mode 100644
index 0000000..b853f87
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionContext.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.jdt.internal.codeassist.InternalCompletionContext;
+
+/**
+ * Completion context.
+ * 
+ * Represent the context in which the completion occurs.
+ * 
+ * @see CompletionRequestor#acceptContext(CompletionContext)
+ * @since 3.1
+ */
+public final class CompletionContext extends InternalCompletionContext {
+	/**
+	 * Return signatures of expected types of a potential completion proposal at the completion position.
+	 * 
+	 * It's not mandatory to a completion proposal to respect this expectation. 
+	 * 
+	 * @return signatures expected types of a potential completion proposal at the completion position or
+	 * <code>null</code> if there is no expected types.
+	 * 
+	 * @see Signature
+	 */
+	public char[][] getExpectedTypesSignatures() {
+		return this.expectedTypesSignatures;
+	}
+	/**
+	 * Return keys of expected types of a potential completion proposal at the completion position.
+	 * 
+	 * It's not mandatory to a completion proposal to respect this expectation. 
+	 * 
+	 * @return keys of expected types of a potential completion proposal at the completion position or
+	 * <code>null</code> if there is no expected types.
+	 * 
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public char[][] getExpectedTypesKeys() {
+		return this.expectedTypesKeys;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
index 83a2df8..9c210fb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionProposal.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -65,10 +65,16 @@
 	 * <li>{@link #getDeclarationSignature()} -
 	 * the type signature of the type being implemented or subclassed
 	 * </li>
+	 * <li>{@link #getDeclarationKey()} -
+	 * the type unique key of the type being implemented or subclassed
 	 * </li>
 	 * <li>{@link #getSignature()} -
 	 * the method signature of the constructor that is referenced
 	 * </li>
+	 * <li>{@link #getKey()} -
+	 * the method unique key of the constructor that is referenced
+	 * if the declaring type is not an interface
+	 * </li>
 	 * <li>{@link #getFlags()} -
 	 * the modifiers flags of the constructor that is referenced
 	 * </li>
@@ -216,6 +222,10 @@
 	 * the type signature of the type that declares the
 	 * method that is being overridden or implemented
 	 * </li>
+	 * <li>{@link #getDeclarationKey()} -
+	 * the unique of the type that declares the
+	 * method that is being overridden or implemented
+	 * </li>
 	 * <li>{@link #getName()} -
 	 * the simple name of the method that is being overridden
 	 * or implemented
@@ -224,6 +234,10 @@
 	 * the method signature of the method that is being
 	 * overridden or implemented
 	 * </li>
+	 * <li>{@link #getKey()} -
+	 * the method unique key of the method that is being
+	 * overridden or implemented
+	 * </li>
 	 * <li>{@link #getFlags()} -
 	 * the modifiers flags of the method that is being
 	 * overridden or implemented
@@ -334,6 +348,7 @@
 	 * </p>
 	 * 
 	 * @see #getKind()
+     * @since 3.1
 	 */
 	public static final int POTENTIAL_METHOD_DECLARATION = 11;
 	
@@ -362,10 +377,56 @@
 	 * </p>
 	 * 
 	 * @see #getKind()
+     * @since 3.1
 	 */
 	public static final int METHOD_NAME_REFERENCE = 12;
 	
 	/**
+	 * Completion is a reference to annotation's attribute.
+	 * This kind of completion might occur in a context like
+	 * <code>"@Annot(attr^=value)"</code> and complete it to
+	 * <code>"@Annot(attribute^=value)"</code>.
+	 * <p>
+	 * The following additional context information is available
+	 * for this kind of completion proposal at little extra cost:
+	 * <ul>
+	 * <li>{@link #getDeclarationSignature()} -
+	 * the type signature of the annotation that declares the attribute that is referenced
+	 * </li>
+	 * <li>{@link #getFlags()} -
+	 * the modifiers flags of the attribute that is referenced
+	 * </li>
+	 * <li>{@link #getName()} -
+	 * the simple name of the attribute that is referenced
+	 * </li>
+	 * <li>{@link #getSignature()} -
+	 * the type signature of the attribute's type (as opposed to the
+	 * signature of the type in which the referenced attribute
+	 * is declared)
+	 * </li>
+	 * </ul>
+	 * </p>
+	 * 
+	 * @see #getKind()
+	 * @since 3.1
+	 */
+	public static final int ANNOTATION_ATTRIBUTE_REF = 13;
+	
+	/**
+	 * First valid completion kind.
+	 * 
+	 * @since 3.1
+	 */
+	protected static final int FIRST_KIND = ANONYMOUS_CLASS_DECLARATION;
+	
+	/**
+	 * Last valid completion kind.
+	 * 
+	 * @since 3.1
+	 */
+	protected static final int LAST_KIND = ANNOTATION_ATTRIBUTE_REF;
+	
+	/**
 	 * Kind of completion request.
 	 */
 	private int completionKind;
@@ -423,6 +484,13 @@
 	private char[] declarationSignature = null;
 	
 	/**
+	 * Unique key of the relevant package or type declaration
+	 * in the context, or <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] declarationKey = null;
+	
+	/**
 	 * Simple name of the method, field,
 	 * member, or variable relevant in the context, or
 	 * <code>null</code> if none.
@@ -438,6 +506,13 @@
 	private char[] signature = null;
 	
 	/**
+	 * Unique of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * Defaults to null.
+	 */
+	private char[] key = null;
+	
+	/**
 	 * Modifier flags relevant in the context, or
 	 * <code>Flags.AccDefault</code> if none.
 	 * Defaults to <code>Flags.AccDefault</code>.
@@ -486,8 +561,8 @@
 	 * @param completionLocation original offset of code completion request
 	 */
 	CompletionProposal(int kind, int completionLocation) {
-		if ((kind < CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
-				|| (kind > CompletionProposal.METHOD_NAME_REFERENCE)) {
+		if ((kind < CompletionProposal.FIRST_KIND)
+				|| (kind > CompletionProposal.LAST_KIND)) {
 			throw new IllegalArgumentException();
 		}
 		if (this.completion == null || completionLocation < 0) {
@@ -606,16 +681,16 @@
 					int start = 0;
 					int end = CharOperation.indexOf('%', this.completion);
 	
-					completionBuffer.append(CharOperation.subarray(this.completion, start, end));
+					completionBuffer.append(this.completion, start, end - start);
 					
 					for(int i = 0 ; i < length ; i++){
 						completionBuffer.append(this.parameterNames[i]);
 						start = end + 1;
 						end = CharOperation.indexOf('%', this.completion, start);
 						if(end > -1){
-							completionBuffer.append(CharOperation.subarray(this.completion, start, end));
+							completionBuffer.append(this.completion, start, end - start);
 						} else {
-							completionBuffer.append(CharOperation.subarray(this.completion, start, this.completion.length));
+							completionBuffer.append(this.completion, start, this.completion.length - start);
 						}
 					}
 					int nameLength = completionBuffer.length();
@@ -746,6 +821,8 @@
 	 * This field is available for the following kinds of
 	 * completion proposals:
 	 * <ul>
+	 *  <li><code>ANNOTATION_ATTRIBUT_REF</code> - type signature
+	 * of the annotation that declares the attribute that is referenced</li>
 	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - type signature
 	 * of the type that is being subclassed or implemented</li>
 	 * 	<li><code>FIELD_REF</code> - type signature
@@ -776,6 +853,32 @@
 	}
 	
 	/**
+	 * Returns the key of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - key
+	 * of the type that is being subclassed or implemented</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - key
+	 * of the type that declares the method that is being
+	 * implemented or overridden</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 * 
+	 * @return a key, or <code>null</code> if none
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, IProgressMonitor)
+     * @since 3.1
+	 */
+	public char[] getDeclarationKey() {
+		return this.declarationKey;
+	}
+	
+	/**
 	 * Sets the type or package signature of the relevant
 	 * declaration in the context, or <code>null</code> if none.
 	 * <p>
@@ -794,6 +897,25 @@
 	}
 	
 	/**
+	 * Sets the type or package key of the relevant
+	 * declaration in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 * 
+	 * @param key the type or package key, or
+	 * <code>null</code> if none
+     * @since 3.1
+	 */
+	public void setDeclarationKey(char[] key) {
+		this.declarationKey = key;
+	}
+	
+	/**
 	 * Returns the simple name of the method, field,
 	 * member, or variable relevant in the context, or
 	 * <code>null</code> if none.
@@ -801,6 +923,7 @@
 	 * This field is available for the following kinds of
 	 * completion proposals:
 	 * <ul>
+	 *  <li><code>ANNOTATION_ATTRIBUT_REF</code> - the name of the attribute</li>
 	 * 	<li><code>FIELD_REF</code> - the name of the field</li>
 	 * 	<li><code>KEYWORD</code> - the keyword</li>
 	 * 	<li><code>LABEL_REF</code> - the name of the label</li>
@@ -849,6 +972,8 @@
 	 * This field is available for the following kinds of
 	 * completion proposals:
 	 * <ul>
+	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - the type signature
+	 * of the referenced attribute's type</li>
 	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method signature
 	 * of the constructor that is being invoked</li>
 	 * 	<li><code>FIELD_REF</code> - the type signature
@@ -878,6 +1003,32 @@
 		return this.signature;
 	}
 	
+	/**
+	 * Returns the key relevant in the context,
+	 * or <code>null</code> if none.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - method key
+	 * of the constructor that is being invoked, or <code>null</code> if
+	 * the declaring type is an interface</li>
+	 * 	<li><code>METHOD_DECLARATION</code> - method key
+	 * of the method that is being implemented or overridden</li>
+	 * </ul>
+	 * For kinds of completion proposals, this method returns
+	 * <code>null</code>. Clients must not modify the array
+	 * returned.
+	 * </p>
+	 * 
+	 * @return the key, or <code>null</code> if none
+	 * @see org.eclipse.jdt.core.dom.ASTParser#createASTs(ICompilationUnit[], String[], org.eclipse.jdt.core.dom.ASTRequestor, IProgressMonitor)
+     * @since 3.1
+	 */
+	public char[] getKey() {
+		return this.key;
+	}
+	
 //	/**
 //	 * Returns the package name of the relevant
 //	 * declaration in the context, or <code>null</code> if none.
@@ -1101,12 +1252,32 @@
 	}
 	
 	/**
+	 * Sets the key of the method, field type, member type,
+	 * relevant in the context, or <code>null</code> if none.
+	 * <p>
+	 * If not set, defaults to none.
+	 * </p>
+	 * <p>
+	 * The completion engine creates instances of this class and sets
+	 * its properties; this method is not intended to be used by other clients.
+	 * </p>
+	 * 
+	 * @param key the key, or <code>null</code> if none
+     * @since 3.1
+	 */
+	public void setKey(char[] key) {
+		this.key = key;
+	}
+	
+	/**
 	 * Returns the modifier flags relevant in the context, or
 	 * <code>Flags.AccDefault</code> if none.
 	 * <p>
 	 * This field is available for the following kinds of
 	 * completion proposals:
 	 * <ul>
+	 * <li><code>ANNOTATION_ATTRIBUT_REF</code> - modifier flags
+	 * of the attribute that is referenced; 
 	 * <li><code>ANONYMOUS_CLASS_DECLARATION</code> - modifier flags
 	 * of the constructor that is referenced</li>
 	 * 	<li><code>FIELD_REF</code> - modifier flags
@@ -1243,4 +1414,28 @@
 		this.parameterNames = parameterNames;
 		this.parameterNamesComputed = true;
 	}
+	
+	/**
+	 * Returns the accessibility of the proposal.
+	 * <p>
+	 * This field is available for the following kinds of
+	 * completion proposals:
+	 * <ul>
+	 * 	<li><code>TYPE_REF</code> - accessibility of the type</li>
+	 * </ul>
+	 * For these kinds of completion proposals, this method returns
+	 * {@link IAccessRule#K_ACCESSIBLE} or {@link IAccessRule#K_DISCOURAGED}
+	 * or {@link IAccessRule#K_NON_ACCESSIBLE}.
+	 * By default this method return {@link IAccessRule#K_ACCESSIBLE}.
+	 * </p>
+	 * 
+	 * @see IAccessRule
+	 * 
+	 * @return the accessibility of the proposal
+	 * 
+	 * @since 3.1
+	 */
+	public int getAccessibility() {
+		return this.accessibility;
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java
index 4fdbee8..f2654b6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,6 +23,7 @@
  * requestors in the following sequence:
  * <pre>
  * requestor.beginReporting();
+ * requestor.acceptContext(context);
  * requestor.accept(proposal_1);
  * requestor.accept(proposal_2);
  * ...
@@ -34,11 +35,13 @@
  * In this case, the sequence of calls is:
  * <pre>
  * requestor.beginReporting();
+ * requestor.acceptContext(context);
  * requestor.completionFailure(problem);
  * requestor.endReporting();
  * </pre>
  * In either case, the bracketing <code>beginReporting</code>
- * <code>endReporting</code> calls are always made.
+ * <code>endReporting</code> calls are always made as well as
+ * <code>acceptContext</code> call.
  * </p>
  * <p>
  * The class was introduced in 3.0 as a more evolvable replacement
@@ -78,8 +81,8 @@
 	 * @see CompletionProposal#getKind()
 	 */
 	public final boolean isIgnored(int completionProposalKind) {
-		if (completionProposalKind < CompletionProposal.ANONYMOUS_CLASS_DECLARATION
-			|| completionProposalKind > CompletionProposal.METHOD_NAME_REFERENCE) {
+		if (completionProposalKind < CompletionProposal.FIRST_KIND
+			|| completionProposalKind > CompletionProposal.LAST_KIND) {
 				throw new IllegalArgumentException();
 		}
 		return 0 != (this.ignoreSet & (1 << completionProposalKind));
@@ -97,8 +100,8 @@
 	 * @see CompletionProposal#getKind()
 	 */
 	public final void setIgnored(int completionProposalKind, boolean ignore) {
-		if (completionProposalKind < CompletionProposal.ANONYMOUS_CLASS_DECLARATION
-			|| completionProposalKind > CompletionProposal.METHOD_NAME_REFERENCE) {
+		if (completionProposalKind < CompletionProposal.FIRST_KIND
+			|| completionProposalKind > CompletionProposal.LAST_KIND) {
 				throw new IllegalArgumentException();
 		}
 		if (ignore) {
@@ -155,11 +158,27 @@
 	 * Similarly, implementers should check 
 	 * {@link #isIgnored(int) isIgnored(proposal.getKind())} 
 	 * and ignore proposals that have been declared as uninteresting.
-	 * The proposal object passed in only valid for the duration of
-	 * this call; implementors must not hang on to these objects.
+	 * The proposal object passed is only valid for the duration of
+	 * completion operation.
 	 * 
 	 * @param proposal the completion proposal
 	 * @exception IllegalArgumentException if the proposal is null
 	 */
 	public abstract void accept(CompletionProposal proposal);
+	
+	/**
+	 * Propose the context in which the completion occurs.
+	 * <p>
+	 * This method is called one and only one time before any call to
+	 * {@link #accept(CompletionProposal)}.
+	 * The default implementation of this method does nothing.
+	 * Clients may override.
+	 * </p>
+	 * @param context the completion context
+	 * 
+	 * @since 3.1
+	 */
+	public void acceptContext(CompletionContext context) {
+		// do nothing
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java
index 7836a68..1cc38aa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestorAdapter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
index db4b2ee..fde348e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CorrectionEngine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,6 +18,7 @@
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
 import org.eclipse.jdt.internal.compiler.parser.*;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -144,7 +145,7 @@
 	 */
 	public void computeCorrections(IProblem problem, ICompilationUnit targetUnit, ICorrectionRequestor requestor) throws JavaModelException {
 		if (requestor == null) {
-			throw new IllegalArgumentException(Util.bind("correction.nullUnit")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.correction_nullUnit);
 		}
 		this.computeCorrections(
 			targetUnit, problem.getID(), 
@@ -184,7 +185,7 @@
 		if(id == -1 || arguments == null || start == -1 || end == -1)
 			return;		
 		if (requestor == null) {
-			throw new IllegalArgumentException(Util.bind("correction.nullRequestor")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.correction_nullRequestor);
 		}
 		
 		this.correctionRequestor = requestor;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java
index 62dd7a3..00a51c4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ElementChangedEvent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java
index 0d5820f..1097d50 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Flags.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added constant AccDefault
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
new file mode 100644
index 0000000..c790e0d
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IAccessRule.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Describes an access rule to source and class files on a classpath entry.
+ * An access rule is composed of a file pattern and a kind (accessible,
+ * non accessible, or discouraged).
+ * <p>
+ * On a given classpath entry, the access rules are considered in the order given
+ * when the entry was created. When a source or class file matches an access 
+ * rule's pattern, the access rule's kind define whether the file is considered
+ * accessible, non accessible, or its access is discouraged. If the source or class
+ * file doesn't match any accessible rule, it is considered accessible. A source or class 
+ * file that is not accessible or discouraged can still be refered to but it is tagged as being not 
+ * accessible - the Java builder will create a problem marker for example. 
+ * The severity of the marker created from a non accessible rule is controled through
+ * the {@link JavaCore#COMPILER_PB_FORBIDDEN_REFERENCE} compiler option.
+ * The severity of the marker created from a discouraged rule is controled through
+ * the {@link JavaCore#COMPILER_PB_DISCOURAGED_REFERENCE} compiler option.
+ * Note this is different from inclusion and exclusion patterns on source classpath entries, 
+ * where a source file that is excluded is not even compiled.
+ * Files patterns look like relative file paths with wildcards and are interpreted relative 
+ * to each entry's path. 
+ * File patterns are case-sensitive and they can contain '**', '*' or '?' wildcards (see 
+ * {@link IClasspathEntry#getExclusionPatterns()} for the full description
+ * of their syntax and semantics).
+ * </p>
+ * <p>
+ * For example, if one of the entry path is <code>/Project/someLib.jar</code>, 
+ * there are no accessible rules, and there is one non accessible rule whith pattern 
+ * <code>com/xyz/tests/&#42;&#42;</code>, then class files
+ * like <code>/Project/someLib.jar/com/xyz/Foo.class</code>
+ * and <code>/Project/someLib.jar/com/xyz/utils/Bar.class</code> would be accessible,
+ * whereas <code>/Project/someLib.jar/com/xyz/tests/T1.class</code>
+ * and <code>/Project/someLib.jar/com/xyz/tests/quick/T2.class</code> would not be
+ * accessible. 
+ * </p>
+ * 
+ * @since 3.1
+ */
+public interface IAccessRule {
+	
+	/**
+	 * Constant indicating that files matching the rule's pattern are accessible.
+	 */
+	int K_ACCESSIBLE = 0;
+	
+	/**
+	 * Constant indicating that files matching the rule's pattern are non accessible.
+	 */
+	int K_NON_ACCESSIBLE = 1;
+
+	/**
+	 * Constant indicating that access to the files matching the rule's pattern is discouraged.
+	 */
+	int K_DISCOURAGED = 2;
+
+	/**
+	 * Returns the file pattern for this access rule.
+	 * 
+	 * @return the file pattern for this access rule
+	 */
+	IPath getPattern();
+	
+	/**
+	 * Returns the kind of this access rule (one of {@link #K_ACCESSIBLE}, {@link #K_NON_ACCESSIBLE}
+	 * or {@link #K_DISCOURAGED}).
+	 * 
+	 * @return the kind of this access rule
+	 */
+	int getKind();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java
index 333f341..79b59af 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBuffer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java
index 4c9f1a7..b790380 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferChangedListener.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java
index e5734e8..171c64e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IBufferFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java
index 0b4a4b9..6d06467 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClassFile.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java
new file mode 100644
index 0000000..74625ab
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathAttribute.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core;
+
+/**
+ * A classpath attribute defines a name/value pair that can be persisted with a classpath entry. Such an attribute
+ * can be created using the factory method {@link JavaCore#newClasspathAttribute(String, String) newClasspathAttribute(String name, String value)}.
+ * 
+ * @see JavaCore#newContainerEntry(
+ *			org.eclipse.core.runtime.IPath containerPath, 
+ *			IAccessRule[] accessRules, 
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @see JavaCore#newLibraryEntry(
+ *			org.eclipse.core.runtime.IPath path,
+ *			org.eclipse.core.runtime.IPath sourceAttachmentPath,
+ *			org.eclipse.core.runtime.IPath sourceAttachmentRootPath,
+ *			IAccessRule[] accessRules, 
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @see JavaCore#newProjectEntry(
+ *			org.eclipse.core.runtime.IPath path, 
+ *			IAccessRule[] accessRules, 
+ *			boolean combineAccessRestrictions,
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)	
+ * @see JavaCore#newSourceEntry(
+ * 			org.eclipse.core.runtime.IPath path, 
+ * 			org.eclipse.core.runtime.IPath[] inclusionPatterns, 
+ * 			org.eclipse.core.runtime.IPath[] exclusionPatterns, 
+ * 			org.eclipse.core.runtime.IPath specificOutputLocation, 
+ * 			IClasspathAttribute[] extraAttributes)
+ * @see JavaCore#newVariableEntry(
+ *			org.eclipse.core.runtime.IPath variablePath,
+ *			org.eclipse.core.runtime.IPath variableSourceAttachmentPath,
+ *			org.eclipse.core.runtime.IPath variableSourceAttachmentRootPath,
+ *			IAccessRule[] accessRules, 
+ *			IClasspathAttribute[] extraAttributes,
+ *			boolean isExported)
+ * @since 3.1
+ */
+public interface IClasspathAttribute {
+	
+	/**
+	 * Constant for the name of the javadoc location attribute.
+	 * 
+	 * @since 3.1
+	 */
+	String JAVADOC_LOCATION_ATTRIBUTE_NAME = "javadoc_location"; //$NON-NLS-1$
+	
+	/**
+	 * Returns the name of this classpath attribute.
+	 * 
+	 * @return the name of this classpath attribute.
+	 * @since 3.1
+	 */
+	String getName();
+	
+	/**
+	 * Returns the value of this classpath attribute.
+	 * 
+	 * @return the value of this classpath attribute.
+	 * @since 3.1
+	 */
+	String getValue();
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java
index 470e510..28b5b44 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java
index fefff5d..7e9ff1a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -146,8 +146,25 @@
 	 * @since 2.0
 	 */
 	int CPE_CONTAINER = 5;
+	
+	/**
+	 * Returns whether the access rules of the project's exported entries should be combined with this entry's access rules.
+	 * Returns true for container entries.
+	 * Returns false otherwise.
+	 * 
+	 * @return whether the access rules of the project's exported entries should be combined with this entry's access rules
+	 * @since 3.1
+	 */
+	boolean combineAccessRules();
 
 	/**
+	 * Returns the possibly empty list of access rules for this entry.
+	 * 
+	 * @return the possibly empty list of access rules for this entry
+	 * @since 3.1
+	 */
+	IAccessRule[] getAccessRules();
+	/**
 	 * Returns the kind of files found in the package fragments identified by this
 	 * classpath entry.
 	 *
@@ -200,15 +217,6 @@
 	 * because a source entry filters these out automatically.
 	 * </p>
 	 * <p>
-	 * Exclusion patterns on library, project, container,
-	 * and variable classpath entries (added in 3.1) are used in a similar
-	 * fashion to express access restrictions. Each path
-	 * specified is relative path encoding a package-qualified class name
-	 * (e.g., <code>java/lang/String</code>). Class names that match
-	 * the exclusion pattern should not be referred to by source code in the
-	 * project (compiler will generate a warning or error).
-	 * </p>
-	 * <p>
 	 * The pattern mechanism is similar to Ant's. Each pattern is represented as
 	 * a relative path. The path segments can be regular file or folder names or simple patterns
 	 * involving standard wildcard characters.
@@ -272,6 +280,15 @@
 	IPath[] getExclusionPatterns();
 	
 	/**
+	 * Returns the extra classpath attributes for this classpath entry. Returns an empty array if this entry
+	 * has no extra attributes.
+	 * 
+	 * @return the possibly empty list of extra classpath attributes for this classpath entry
+	 * @since 3.1
+	 */
+	IClasspathAttribute[] getExtraAttributes();
+	
+	/**
 	 * Returns the set of patterns used to explicitly define resources or classes
 	 * to be included with this classpath entry.
 	 * <p>
@@ -289,15 +306,6 @@
 	 * ones that are to be included, not the other way around.
 	 * </p>
 	 * <p>
-	 * Inclusion patterns on library, project, container,
-	 * and variable classpath entries (added in 3.1) are used in a similar
-	 * fashion to express access restrictions. Each path
-	 * specified is relative path encoding a package-qualified class name
-	 * (e.g., <code>java/lang/String</code>). Class names that match
-	 * the inclusion pattern can be legally referred to by source code in the
-	 * project.
-	 * </p>
-	 * <p>
 	 * See {@link #getExclusionPatterns()} for a discussion of the syntax and
 	 * semantics of path patterns. The absence of any inclusion patterns is
 	 * semantically equivalent to the explicit inclusion pattern
@@ -326,7 +334,7 @@
 	 * 
 	 * @return the possibly empty list of resource inclusion patterns 
 	 *   associated with this classpath entry, or <code>null</code> if this kind
-	 *   of classpath entry does not support exclusion patterns
+	 *   of classpath entry does not support inclusion patterns
 	 * @since 3.0
 	 */
 	IPath[] getInclusionPatterns();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java
index eac0384..254e3a0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeAssist.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -63,11 +63,6 @@
 		throws JavaModelException;
 	
 	/**
-	 * <b>DO NOT USE</b>: This API element was added in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0.
-	 * It is currently unimplemented, and the API may change slightly before
-	 * reaching its final form.
-	 * <p>
 	 * Performs code completion at the given offset position in this compilation unit,
 	 * reporting results to the given completion requestor. The <code>offset</code>
 	 * is the 0-based index of the character, after which code assist is desired.
@@ -120,11 +115,6 @@
 		throws JavaModelException;
 
 	/**
-	 * <b>DO NOT USE</b>: This API element was added in anticipation of J2SE
-	 * 1.5 support, which is planned for the next release of Eclipse after 3.0.
-	 * It is currently unimplemented, and the API may change slightly before
-	 * reaching its final form.
-	 * <p>
 	 * Performs code completion at the given offset position in this compilation unit,
 	 * reporting results to the given completion requestor. The <code>offset</code>
 	 * is the 0-based index of the character, after which code assist is desired.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java
index d61e61e..86ef806 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeCompletionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java
index 87df2a8..e44e348 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICodeFormatter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
index a659a0e..3f5be18 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added J2SE 1.5 support
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java
index d387520..859e9ca 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompletionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java
index a3f2be2..0711231 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICorrectionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java
index 57a1cf8..64fadc8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IElementChangedListener.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java
index 0ed0fd1..9f22866 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added J2SE 1.5 support
@@ -95,6 +95,17 @@
  */
 String getElementName();
 /**
+ * Returns the binding key for this field. A binding key is a key that uniquely
+ * identifies this field. It allows access to generic info for parameterized
+ * fields.
+ * 
+ * @return the binding key for this field
+ * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+ * @see BindingKey
+ * @since 3.1
+ */
+String getKey();
+/**
  * Returns the type signature of this field. For enum constants,
  * this returns the signature of the declaring enum class.
  * <p>
@@ -109,4 +120,22 @@
  * @see Signature
  */
 String getTypeSignature() throws JavaModelException;
+/**
+ * Returns whether this field represents an enum constant.
+ * 
+ * @return whether this field represents an enum constant
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource
+ * @since 3.1
+ */
+boolean isEnumConstant() throws JavaModelException;
+/**
+ * Returns whether this field represents a resolved field.
+ * If a field is resoved, its key contains resolved information.
+ * 
+ * @return whether this field represents a resolved field.
+ * @since 3.1
+ */
+boolean isResolved();
+
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java
index 2756f22..691ab5b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportContainer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java
index 747ede1..1b081f6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IImportDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added J2SE 1.5 support
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java
index 5aafc31..2bf888a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java
index c55c7fb..ba23088 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java
index 9d33d43..98fcbf6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaElementDelta.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java
index 454d9f3..b646b91 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModel.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java
index 39c97f0..a33ba49 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelMarker.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java
index 6961579..c90b830 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatus.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
index d29c6e2..65b294d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaModelStatusConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  * 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
index 49d0e22..422c51a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added getOption(String, boolean), getOptions(boolean) and setOptions(Map)
@@ -867,4 +867,4 @@
 	 */
 	void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation, IProgressMonitor monitor)
 		throws JavaModelException;
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java
index 585e9f3..1ce2918 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ILocalVariable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java
index 40e52b3..ff5cc71 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMember.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
index d12fc3b..8040eeb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added J2SE 1.5 support
@@ -87,6 +87,17 @@
  */
 int getNumberOfParameters();
 /**
+ * Returns the binding key for this method. A binding key is a key that uniquely
+ * identifies this method. It allows access to generic info for parameterized
+ * methods.
+ * 
+ * @return the binding key for this method
+ * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+ * @see BindingKey
+ * @since 3.1
+ */
+String getKey();
+/**
  * Returns the names of parameters in this method.
  * For binary types, these names are invented as "arg"+i, where i starts at 1 
  * (even if source is associated with the binary).
@@ -195,6 +206,14 @@
  */
 boolean isMainMethod() throws JavaModelException;
 /**
+ * Returns whether this method represents a resolved method.
+ * If a method is resoved, its key contains resolved information.
+ * 
+ * @return whether this method represents a resolved method.
+ * @since 3.1
+ */
+boolean isResolved();
+/**
  * Returns whether this method is similar to the given method.
  * Two methods are similar if:
  * <ul>
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java
index c221c91..d0f4e5d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IOpenable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java
index 50eadd8..597977c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java
index bbf0181..0ae4a74 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
index a3e21fd..527f119 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IPackageFragmentRoot.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - specified that a source archive or a source folder can be attached to a binary
@@ -428,4 +428,4 @@
 	 * @since 2.1
 	 */
 	void move(IPath destination, int updateResourceFlags, int updateModelFlags, IClasspathEntry sibling, IProgressMonitor monitor) throws JavaModelException;
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java
index dd81aa8..66b9379 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IParent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java
index adbc287..2dc0c95 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IProblemRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java
index 32bc1dd..b621ede 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IRegion.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java
index 14a1530..d19b1c7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceManipulation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java
index 0070046..468c048 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceRange.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java
index b170a92..3e7b79c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ISourceReference.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
index 7cb804d..993f2cc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added J2SE 1.5 support
@@ -450,6 +450,18 @@
 	IInitializer[] getInitializers() throws JavaModelException;
 	
 	/**
+	 * Returns the binding key for this type. A binding key is a key that uniquely
+	 * identifies this type. It allows access to generic info for parameterized
+	 * types.
+	 * 
+	 * @return the binding key for this type
+	 * @see org.eclipse.jdt.core.dom.IBinding#getKey()
+	 * @see BindingKey
+	 * @since 3.1
+	 */
+	String getKey();
+	
+	/**
 	 * Returns the method with the specified name and parameter types
 	 * in this type (for example, <code>"foo", {"I", "QString;"}</code>).
 	 * To get the handle for a constructor, the name specified must be the
@@ -592,7 +604,6 @@
 	 * in the order declared in the source, an empty array if none
 	 * @see Signature
 	 * @since 3.0
-	 * @deprecated Use #getTypeParameters() instead
 	 */
 	String[] getTypeParameterSignatures() throws JavaModelException;
 	
@@ -695,9 +706,7 @@
 	/**
 	 * Returns whether this type represents a class.
 	 * <p>
-	 * Note that <code>isClass</code>, <code>isInterface</code>,
-	 * <code>isEnum</code>, and <code>isAnnotation</code> are
-	 * mutually exclusive.
+	 * Note that a class can neither be an interface, an enumeration class, nor an annotation type.
 	 * </p>
 	 *
 	 * @exception JavaModelException if this element does not exist or if an
@@ -709,9 +718,7 @@
 	/**
 	 * Returns whether this type represents an enumeration class.
 	 * <p>
-	 * Note that <code>isClass</code>, <code>isInterface</code>,
-	 * <code>isEnum</code>, and <code>isAnnotation</code> are
-	 * mutually exclusive.
+	 * Note that an enumeration class can neither be a class, an interface, nor an annotation type.
 	 * </p>
 	 * 
 	 * @exception JavaModelException if this element does not exist or if an
@@ -725,9 +732,7 @@
 	/**
 	 * Returns whether this type represents an interface.
 	 * <p>
-	 * Note that <code>isClass</code>, <code>isInterface</code>,
-	 * <code>isEnum</code>, and <code>isAnnotation</code> are
-	 * mutually exclusive.
+	 * Note that an interface can also be an annotation type, but it can neither be a class nor an enumeration class.
 	 * </p>
 	 *
 	 * @exception JavaModelException if this element does not exist or if an
@@ -739,9 +744,7 @@
 	/**
 	 * Returns whether this type represents an annotation type.
 	 * <p>
-	 * Note that <code>isClass</code>, <code>isInterface</code>,
-	 * <code>isEnum</code>, and <code>isAnnotation</code> are
-	 * mutually exclusive.
+	 * Note that an annotation type is also an interface, but it can neither be a class nor an enumeration class. 
 	 * </p>
 	 *
 	 * @exception JavaModelException if this element does not exist or if an
@@ -772,6 +775,14 @@
 	 */
 	boolean isMember() throws JavaModelException;
 	/**
+	 * Returns whether this type represents a resolved type.
+	 * If a type is resoved, its key contains resolved information.
+	 * 
+	 * @return whether this type represents a resolved type.
+	 * @since 3.1
+	 */
+	boolean isResolved();
+	/**
 	 * Loads a previously saved ITypeHierarchy from an input stream. A type hierarchy can
 	 * be stored using ITypeHierachy#store(OutputStream).
 	 * 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java
index 99b9550..64ef993 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchy.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java
index 4ae1ee7..335a320 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeHierarchyChangedListener.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java
index cac2888..26ccbc5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ITypeParameter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java
index 32b6d45..c034623 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IWorkingCopy.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
index 6c7e56d..9e0e675 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,7 +25,7 @@
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.JavaModelStatus;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * Provides methods for checking Java-specific conventions such as name syntax.
@@ -125,16 +125,16 @@
 	 */
 	public static IStatus validateCompilationUnitName(String name) {
 		if (name == null) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.unit.nullName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_nullName, null); 
 		}
 		if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(name)) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.unit.notJavaName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null); 
 		}
 		String identifier;
 		int index;
 		index = name.lastIndexOf('.');
 		if (index == -1) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.unit.notJavaName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_unit_notJavaName, null); 
 		}
 		identifier = name.substring(0, index);
 		// JSR-175 metadata strongly recommends "package-info.java" as the
@@ -172,16 +172,15 @@
 	 */
 	public static IStatus validateClassFileName(String name) {
 		if (name == null) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.classFile.nullName"), null); //$NON-NLS-1$
-		}
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_nullName, null);		}
 		if (!org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(name)) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.classFile.notClassFileName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null); 
 		}
 		String identifier;
 		int index;
 		index = name.lastIndexOf('.');
 		if (index == -1) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.classFile.notClassFileName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_classFile_notClassFileName, null); 
 		}
 		identifier = name.substring(0, index);
 		IStatus status = validateIdentifier(identifier);
@@ -226,7 +225,7 @@
 		if (scannedIdentifier(id) != null) {
 			return JavaModelStatus.VERIFIED_OK;
 		} else {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.illegalIdentifier", id), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, id), null); 
 		}
 	}
 
@@ -244,13 +243,13 @@
 	 */
 	public static IStatus validateImportDeclaration(String name) {
 		if (name == null || name.length() == 0) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.import.nullImport"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_nullImport, null); 
 		} 
 		if (name.charAt(name.length() - 1) == '*') {
 			if (name.charAt(name.length() - 2) == '.') {
 				return validatePackageName(name.substring(0, name.length() - 2));
 			} else {
-				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.import.unqualifiedImport"), null); //$NON-NLS-1$
+				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_import_unqualifiedImport, null); 
 			}
 		}
 		return validatePackageName(name);
@@ -271,11 +270,11 @@
 	 */
 	public static IStatus validateJavaTypeName(String name) {
 		if (name == null) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.type.nullName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nullName, null); 
 		}
 		String trimmed = name.trim();
 		if (!name.equals(trimmed)) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.type.nameWithBlanks"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_type_nameWithBlanks, null); 
 		}
 		int index = name.lastIndexOf('.');
 		char[] scannedID;
@@ -299,14 +298,14 @@
 				return status;
 			}
 			if (CharOperation.contains('$', scannedID)) {
-				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Util.bind("convention.type.dollarName"), null); //$NON-NLS-1$
+				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_dollarName, null); 
 			}
 			if ((scannedID.length > 0 && Character.isLowerCase(scannedID[0]))) {
-				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Util.bind("convention.type.lowercaseName"), null); //$NON-NLS-1$
+				return new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_type_lowercaseName, null); 
 			}
 			return JavaModelStatus.VERIFIED_OK;
 		} else {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.type.invalidName", name), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_type_invalidName, (new String[] {name})), null); 
 		}
 	}
 
@@ -346,26 +345,26 @@
 	public static IStatus validatePackageName(String name) {
 
 		if (name == null) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.package.nullName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nullName, null); 
 		}
 		int length;
 		if ((length = name.length()) == 0) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.package.emptyName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_emptyName, null); 
 		}
 		if (name.charAt(0) == DOT || name.charAt(length-1) == DOT) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.package.dotName"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_dotName, null); 
 		}
 		if (CharOperation.isWhitespace(name.charAt(0)) || CharOperation.isWhitespace(name.charAt(name.length() - 1))) {
-			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.package.nameWithBlanks"), null); //$NON-NLS-1$
+			return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_nameWithBlanks, null); 
 		}
 		int dot = 0;
 		while (dot != -1 && dot < length-1) {
 			if ((dot = name.indexOf(DOT, dot+1)) != -1 && dot < length-1 && name.charAt(dot+1) == DOT) {
-				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.package.consecutiveDotsName"), null); //$NON-NLS-1$
+				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.convention_package_consecutiveDotsName, null); 
 				}
 		}
 		IWorkspace workspace = ResourcesPlugin.getWorkspace();
-		StringTokenizer st = new StringTokenizer(name, new String(new char[] {DOT}));
+		StringTokenizer st = new StringTokenizer(name, "."); //$NON-NLS-1$
 		boolean firstToken = true;
 		IStatus warningStatus = null;
 		while (st.hasMoreTokens()) {
@@ -373,7 +372,7 @@
 			typeName = typeName.trim(); // grammar allows spaces
 			char[] scannedID = scannedIdentifier(typeName);
 			if (scannedID == null) {
-				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("convention.illegalIdentifier", typeName), null); //$NON-NLS-1$
+				return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.convention_illegalIdentifier, (new String[] {typeName})), null); 
 			}
 			IStatus status = workspace.validateName(new String(scannedID), IResource.FOLDER);
 			if (!status.isOK()) {
@@ -381,7 +380,7 @@
 			}
 			if (firstToken && scannedID.length > 0 && Character.isUpperCase(scannedID[0])) {
 				if (warningStatus == null) {
-					warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Util.bind("convention.package.uppercaseName"), null); //$NON-NLS-1$
+					warningStatus = new Status(IStatus.WARNING, JavaCore.PLUGIN_ID, -1, Messages.convention_package_uppercaseName, null); 
 				}
 			}
 			firstToken = false;
@@ -442,6 +441,22 @@
 	public static IJavaModelStatus validateClasspathEntry(IJavaProject project, IClasspathEntry entry, boolean checkSourceAttachment){
 		return ClasspathEntry.validateClasspathEntry(project, entry, checkSourceAttachment, true/*recurse in container*/);
 	}
+	
+	/**
+	 * Validate the given type variable name.
+	 * <p>
+	 * Syntax of a type variable name corresponds to a Java identifier (JLS3 4.3).
+	 * For example, <code>"E"</code>.
+	 *
+	 * @param name the name of a type variable
+	 * @return a status object with code <code>IStatus.OK</code> if
+	 *		the given name is valid as a type variable name, otherwise a status 
+	 *		object indicating what is wrong with the name
+	 * @since 3.1
+	 */
+	public static IStatus validateTypeVariableName(String name) {
+		return validateIdentifier(name);
+	}
 
 	/**
 	 * Validate that all compiler options of the given project match keys and values
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 7c8013d..4f1abbb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added the following constants:
@@ -64,13 +64,12 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.preferences.DefaultScope;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.core.runtime.preferences.IPreferencesService;
-import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.prefs.BackingStoreException;
@@ -319,6 +318,12 @@
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String COMPILER_PB_TYPE_PARAMETER_HIDING = PLUGIN_ID + ".compiler.problem.typeParameterHiding"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
 	 * @since 3.0
 	 */
 	public static final String COMPILER_PB_POSSIBLE_ACCIDENTAL_BOOLEAN_ASSIGNMENT = PLUGIN_ID + ".compiler.problem.possibleAccidentalBooleanAssignment"; //$NON-NLS-1$
@@ -412,6 +417,36 @@
 	 * @see #getDefaultOptions()
 	 * @since 3.1
 	 */
+	public static final String COMPILER_PB_AUTOBOXING = PLUGIN_ID + ".compiler.problem.autoboxing"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String COMPILER_PB_ANNOTATION_SUPER_INTERFACE = PLUGIN_ID + ".compiler.problem.annotationSuperInterface"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String COMPILER_PB_MISSING_OVERRIDE_ANNOTATION = PLUGIN_ID + ".compiler.problem.missingOverrideAnnotation"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String COMPILER_PB_MISSING_DEPRECATED_ANNOTATION = PLUGIN_ID + ".compiler.problem.missingDeprecatedAnnotation"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String COMPILER_PB_INCOMPLETE_ENUM_SWITCH = PLUGIN_ID + ".compiler.problem.incompleteEnumSwitch"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
 	public static final String COMPILER_PB_INCONSISTENT_NULL_CHECK = PLUGIN_ID + ".compiler.problem.inconsistentNullCheck"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
@@ -548,6 +583,12 @@
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String COMPILER_PB_DISCOURAGED_REFERENCE = PLUGIN_ID + ".compiler.problem.discouragedReference"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
 	 */
 	public static final String CORE_JAVA_BUILD_ORDER = PLUGIN_ID + ".computeJavaBuildOrder"; //$NON-NLS-1$
 	/**
@@ -636,75 +677,78 @@
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION,
-	 * DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_BLOCK, 
-	 * DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION,
-	 * DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION,
-	 * DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_SWITCH,
-	 * DefaultCodeFormatterConstants.FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_BLOCK} ,
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_CONSTRUCTOR_DECLARATION},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_SWITCH},
+	 * {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION} instead
 	 */
 	public static final String FORMATTER_NEWLINE_OPENING_BRACE = PLUGIN_ID + ".formatter.newline.openingBrace"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_CONTROL_STATEMENTS instead.
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT},
+	 *  {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT},
+	 *  {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT},
+	 *  {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT} instead.
 	 */
 	public static final String FORMATTER_NEWLINE_CONTROL = PLUGIN_ID + ".formatter.newline.controlStatement"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_COMPACT_ELSE_IF instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_COMPACT_ELSE_IF} instead
 	 */
 	public static final String FORMATTER_NEWLINE_ELSE_IF = PLUGIN_ID + ".formatter.newline.elseIf"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK} instead
 	 */
 	public static final String FORMATTER_NEWLINE_EMPTY_BLOCK = PLUGIN_ID + ".formatter.newline.emptyBlock"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE} instead
 	 */
 	public static final String FORMATTER_CLEAR_BLANK_LINES = PLUGIN_ID + ".formatter.newline.clearAll"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_LINE_SPLIT} instead
 	 */
 	public static final String FORMATTER_LINE_SPLIT = PLUGIN_ID + ".formatter.lineSplit"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR} instead
 	 */
 	public static final String FORMATTER_COMPACT_ASSIGNMENT = PLUGIN_ID + ".formatter.style.assignment"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_CHAR}} instead
 	 */
 	public static final String FORMATTER_TAB_CHAR = PLUGIN_ID + ".formatter.tabulation.char"; //$NON-NLS-1$
 	/**
 	 * Possible  configurable option ID.
 	 * @see #getDefaultOptions()
 	 * @since 2.0
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_TAB_SIZE} instead
 	 */
 	public static final String FORMATTER_TAB_SIZE = PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
 	/**
 	 * Possible configurable option ID
 	 * @see #getDefaultOptions()
 	 * @since 2.1
-	 * @deprecated Use DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST instead
+	 * @deprecated Use {@link org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants#FORMATTER_INSERT_SPACE_AFTER_CLOSING_PAREN_IN_CAST} instead
 	 */
 	public static final String FORMATTER_SPACE_CASTEXPRESSION = PLUGIN_ID + ".formatter.space.castexpression"; //$NON-NLS-1$
 	/**
@@ -772,7 +816,13 @@
 	 * @see #getDefaultOptions()
 	 * @since 3.1
 	 */
-	public static final String CODEASSIST_RESTRICTIONS_CHECK = PLUGIN_ID + ".codeComplete.restrictionsCheck"; //$NON-NLS-1$
+	public static final String CODEASSIST_FORBIDDEN_REFERENCE_CHECK = PLUGIN_ID + ".codeComplete.restrictionsCheck"; //$NON-NLS-1$
+	/**
+	 * Possible  configurable option ID.
+	 * @see #getDefaultOptions()
+	 * @since 3.1
+	 */
+	public static final String CODEASSIST_DISCOURAGED_REFERENCE_CHECK = PLUGIN_ID + ".codeComplete.discouragedReferenceCheck"; //$NON-NLS-1$
 	
 	// *************** Possible values for configurable options. ********************
 	
@@ -940,14 +990,11 @@
 	 * @since 3.0
 	 */
 	public static final String PRIVATE = "private"; //$NON-NLS-1$
-	
-	/**
-	 * New Preferences API
-	 * @since 3.1
+
+	/*
+	 * Cache for options.
 	 */
-	public static final IEclipsePreferences[] preferencesLookup = new IEclipsePreferences[2];
-	static final int PREF_INSTANCE = 0;
-	static final int PREF_DEFAULT = 1;
+	static Hashtable optionsCache;
 
 	/**
 	 * Creates the Java core plug-in.
@@ -1755,6 +1802,13 @@
 	 *     - possible values:   { "enabled", "disabled" }
 	 *     - default:           "disabled"
 	 * 
+	 * COMPILER / Reporting Type Parameter Declaration Hiding another Type
+	 *    When enabled, the compiler will issue an error or a warning whenever a type parameter
+	 *    declaration is hiding some type.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.typeParameterHiding"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "warning"
+	 *
 	 * COMPILER / Reporting Possible Accidental Boolean Assignment
 	 *    When enabled, the compiler will issue an error or a warning if a boolean assignment is acting as the condition
 	 *    of a control statement  (where it probably was meant to be a boolean comparison).
@@ -1810,7 +1864,7 @@
 	 *    bound corresponding to a final type; since final types cannot be further extended, the parameter is pretty useless.
 	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.finalParameterBound"
 	 *     - possible values:   { "error", "warning", "ignore" }
-	 *     - default:           "ignore"
+	 *     - default:           "warning"
 	 * 
 	 * COMPILER / Reporting Missing Declaration of serialVersionUID Field on Serializable Class
 	 *    When enabled, the compiler will issue an error or a warning whenever a serializable class is missing a local declaration 
@@ -1838,6 +1892,35 @@
 	 *     - possible values:   { "error", "warning", "ignore" }
 	 *     - default:           "warning"
 	 * 
+	 * COMPILER / Reporting Use of Annotation Type as Super Interface
+	 *    When enabled, the compiler will issue an error or a warning whenever an annotation type is used
+	 *    as a super-interface. Though legal, this is discouraged.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.annotationSuperInterface"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "warning"
+	 * 
+	 * COMPILER / Reporting Missing @Override Annotation
+	 *    When enabled, the compiler will issue an error or a warning whenever encountering a method
+	 *    declaration which overrides a superclass method but has no @Override annotation.
+	 *     - option id:        "org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"                               
+	 * 
+	 * COMPILER / Reporting Missing @Deprecated Annotation
+	 *    When enabled, the compiler will issue an error or a warning whenever encountering a declaration
+	 *    carrying a @deprecated doc tag but has no corresponding @Deprecated annotation.
+	 *     - option id:        "org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"                               
+	 * 
+	 * COMPILER / Reporting Incomplete Enum Switch
+	 *    When enabled, the compiler will issue an error or a warning whenever an enum constant has
+	 *    no corresponding case label in an enum switch statement
+	 *    type has no case label matching an enum constant.
+	 *     - option id:        "org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "ignore"                               
+	 * 	
 	 * COMPILER / Reporting Boxing/Unboxing Conversion
 	 *    When enabled, the compiler will issue an error or a warning whenever a boxing or an unboxing
 	 *    conversion is performed.
@@ -1963,12 +2046,19 @@
 	 *     - default:           "enabled"
 	 *
 	 * COMPILER / Reporting Forbidden Reference to Type with Restricted Access
-	 *    When enabled, the compiler will issue an error or a warning when referring to a type with restricted access, as defined according
-	 *    to the access restriction specifications.
+	 *    When enabled, the compiler will issue an error or a warning when referring to a type that is non accessible, as defined according
+	 *    to the access rule specifications.
 	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.forbiddenReference"
 	 *     - possible values:   { "error", "warning", "ignore" }
 	 *     - default:           "warning"
 	 *
+	 * COMPILER / Reporting Discouraged Reference to Type with Restricted Access
+	 *    When enabled, the compiler will issue an error or a warning when referring to a type with discouraged access, as defined according
+	 *    to the access rule specifications.
+	 *     - option id:         "org.eclipse.jdt.core.compiler.problem.discouragedReference"
+	 *     - possible values:   { "error", "warning", "ignore" }
+	 *     - default:           "warning"
+	 *
 	 * BUILDER / Specifying Filters for Resource Copying Control
 	 *    Allow to specify some filters to control the resource copy process.
 	 *     - option id:         "org.eclipse.jdt.core.builder.resourceCopyExclusionFilter"
@@ -2183,12 +2273,18 @@
 	 *     - possible values:   { "&lt;suffix&gt;[,&lt;suffix&gt;]*" } where &lt;suffix&gt; is a String without any wild-card 
 	 *     - default:           ""
 	 *     
-	 *  CODEASSIST / Activate Access Restrictions Sensitive Completion
-	 *    When active, completion doesn't show that is access restricted.
+	 *  CODEASSIST / Activate Forbidden Reference Sensitive Completion
+	 *    When active, completion doesn't show that have forbidden reference.
 	 *     - option id:         "org.eclipse.jdt.core.codeComplete.restrictionsCheck"
 	 *     - possible values:   { "enabled", "disabled" }
 	 *     - default:           "disabled"
 	 * 
+	 *  CODEASSIST / Activate Discouraged Reference Sensitive Completion
+	 *    When active, completion doesn't show that have discouraged reference.
+	 *     - option id:         "org.eclipse.jdt.core.codeComplete.discouragedReferenceCheck"
+	 *     - possible values:   { "enabled", "disabled" }
+	 *     - default:           "disabled"
+	 * 
 	 * </pre>
 	 * 
 	 * @return a mutable table containing the default settings of all known options
@@ -2199,9 +2295,10 @@
 	
 		Hashtable defaultOptions = new Hashtable(10);
 
-		// see #initializeDefaultPluginPreferences() for changing default settings
-		IEclipsePreferences defaultPreferences = getDefaultPreferences();
-		HashSet optionNames = JavaModelManager.getJavaModelManager().optionNames;
+		// see JavaCorePreferenceInitializer#initializeDefaultPluginPreferences() for changing default settings
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		IEclipsePreferences defaultPreferences = manager.getDefaultPreferences();
+		HashSet optionNames = manager.optionNames;
 		
 		// initialize preferences to their default
 		Iterator iterator = optionNames.iterator();
@@ -2218,26 +2315,6 @@
 		
 		return defaultOptions;
 	}
- 
-	/**
-	 * @since 3.1
-	 */
-	public static IEclipsePreferences getInstancePreferences() {
-		if (preferencesLookup[PREF_INSTANCE] == null) {
-			preferencesLookup[PREF_INSTANCE] = new InstanceScope().getNode(PLUGIN_ID);
-		}
-		return preferencesLookup[PREF_INSTANCE];
-	}
- 
-	/**
-	 * @since 3.1
-	 */
-	public static IEclipsePreferences getDefaultPreferences() {
-		if (preferencesLookup[PREF_DEFAULT] == null) {
-			preferencesLookup[PREF_DEFAULT] = new DefaultScope().getNode(PLUGIN_ID);
-		}
-		return preferencesLookup[PREF_DEFAULT];
-	}
 
 	/**
 	 * Returns the workspace root default charset encoding.
@@ -2294,9 +2371,10 @@
 			return ERROR;
 		}
 		String propertyName = optionName;
-		if (JavaModelManager.getJavaModelManager().optionNames.contains(propertyName)){
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		if (manager.optionNames.contains(propertyName)){
 			IPreferencesService service = Platform.getPreferencesService();
-			String value =  service.get(optionName, null, preferencesLookup);
+			String value =  service.get(optionName, null, manager.preferencesLookup);
 			return value==null ? null : value.trim();
 		}
 		return null;
@@ -2316,16 +2394,20 @@
 	 */
 	public static Hashtable getOptions() {
 
+		// return cached options if already computed
+		if (optionsCache != null) return new Hashtable(optionsCache);
+
 		// init
 		Hashtable options = new Hashtable(10);
-		HashSet optionNames = JavaModelManager.getJavaModelManager().optionNames;
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		HashSet optionNames = manager.optionNames;
 		IPreferencesService service = Platform.getPreferencesService();
 
 		// set options using preferences service lookup
 		Iterator iterator = optionNames.iterator();
 		while (iterator.hasNext()) {
 		    String propertyName = (String) iterator.next();
-		    String propertyValue = service.get(propertyName, null, preferencesLookup);
+		    String propertyValue = service.get(propertyName, null, manager.preferencesLookup);
 		    if (propertyValue != null) {
 			    options.put(propertyName, propertyValue);
 		    }
@@ -2338,6 +2420,9 @@
 		options.put(COMPILER_PB_INVALID_IMPORT, ERROR);
 		options.put(COMPILER_PB_UNREACHABLE_CODE, ERROR);
 
+		// store built map in cache
+		optionsCache = new Hashtable(options);
+
 		// return built map
 		return options;
 	}
@@ -2396,8 +2481,12 @@
 					
 					case IResource.PROJECT :  
 						// internal project
-						return JavaCore.newProjectEntry(resolvedPath, entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.isExported());
-						
+						return JavaCore.newProjectEntry(
+								resolvedPath, 
+								entry.getAccessRules(),
+								entry.combineAccessRules(), 
+								entry.getExtraAttributes(), 
+								entry.isExported());
 					case IResource.FILE : 
 						if (org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(resolvedResource.getName())) {
 							// internal binary archive
@@ -2405,8 +2494,8 @@
 									resolvedPath,
 									getResolvedVariablePath(entry.getSourceAttachmentPath()),
 									getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
-									entry.getInclusionPatterns(), 
-									entry.getExclusionPatterns(), 
+									entry.getAccessRules(), 
+									entry.getExtraAttributes(), 
 									entry.isExported());
 						}
 						break;
@@ -2417,8 +2506,8 @@
 								resolvedPath,
 								getResolvedVariablePath(entry.getSourceAttachmentPath()),
 								getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
-								entry.getInclusionPatterns(), 
-								entry.getExclusionPatterns(), 
+								entry.getAccessRules(), 
+								entry.getExtraAttributes(), 
 								entry.isExported());
 				}
 			}
@@ -2434,8 +2523,8 @@
 							resolvedPath,
 							getResolvedVariablePath(entry.getSourceAttachmentPath()),
 							getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
-							entry.getInclusionPatterns(), 
-							entry.getExclusionPatterns(), 
+							entry.getAccessRules(),
+							entry.getExtraAttributes(),
 							entry.isExported());
 				}
 			} else { // external binary folder
@@ -2444,8 +2533,8 @@
 							resolvedPath,
 							getResolvedVariablePath(entry.getSourceAttachmentPath()),
 							getResolvedVariablePath(entry.getSourceAttachmentRootPath()),
-							entry.getInclusionPatterns(), 
-							entry.getExclusionPatterns(), 
+							entry.getAccessRules(),
+							entry.getExtraAttributes(),
 							entry.isExported());
 				}
 			}
@@ -2613,12 +2702,34 @@
 		}
 		return false;
 	}
+	
+	/**
+	 * Creates and returns a new access rule with the given file pattern and kind.
+	 * 
+	 * @param filePattern the file pattern this access rule should match
+	 * @param kind one of IAccessRule#K_ACCESSIBLE, IAcccessRule#K_STRICTLY_NON_ACCESSIBLE, or IAcccessRule#K_LOOSELY_NON_ACCESSIBLE
+	 * @return a new access rule
+	 * @since 3.1
+	 */
+	public static IAccessRule newAccessRule(IPath filePattern, int kind) {
+		return new ClasspathAccessRule(filePattern, kind);
+	}
+	
+	/**
+	 * Creates and returns a new classpath attribute with the given name and the given value.
+	 * 
+	 * @return a new classpath attribute
+	 * @since 3.1
+	 */
+	public static IClasspathAttribute newClasspathAttribute(String name, String value) {
+		return new ClasspathAttribute(name, value);
+	}
 
 	/**
 	 * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
 	 * for the given path. This method is fully equivalent to calling
-	 * {@link #newContainerEntry(IPath, IPath[], IPath[], boolean)
-	 * newContainerEntry(containerPath, new IPath[0], new IPath[0], false)}.
+	 * {@link #newContainerEntry(IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newContainerEntry(containerPath, new IAccessRule[0], new IClasspathAttribute[0], false)}.
 	 * <p>
 	 * @param containerPath the path identifying the container, it must be formed of two
 	 * 	segments
@@ -2628,19 +2739,18 @@
 	 * @since 2.0
 	 */
 	public static IClasspathEntry newContainerEntry(IPath containerPath) {
-			
 		return newContainerEntry(
-			containerPath,
-			ClasspathEntry.INCLUDE_ALL,
-			ClasspathEntry.EXCLUDE_NONE, 
-			false);
+		containerPath,
+		ClasspathEntry.NO_ACCESS_RULES,
+		ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+		false/*not exported*/);
 	}
 
 	/**
 	 * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code>
 	 * for the given path. This method is fully equivalent to calling
-	 * {@link #newContainerEntry(IPath, IPath[], IPath[], boolean)
-	 * newContainerEntry(containerPath, new IPath[0], new IPath[0], isExported)}. 
+	 * {@link #newContainerEntry(IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newContainerEntry(containerPath, new IAccessRule[0], new IClasspathAttribute[0], isExported)}. 
 	 * 
 	 * @param containerPath the path identifying the container, it must be formed of at least
 	 * 	one segment (ID+hints)
@@ -2653,11 +2763,10 @@
 	 * @since 2.0
 	 */
 	public static IClasspathEntry newContainerEntry(IPath containerPath, boolean isExported) {
-			
 		return newContainerEntry(
 			containerPath,
-			ClasspathEntry.INCLUDE_ALL,
-			ClasspathEntry.EXCLUDE_NONE, 
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
 			isExported);
 	}
 
@@ -2692,45 +2801,25 @@
 	 *       class="com.example.MyInitializer"/&gt; 
 	 * </pre>
 	 * <p>
-	 * The inclusion patterns determines the initial set of accessible source and class files in 
-	 * the container; the exclusion patterns are then used to reduce this
-	 * set. A source or class file that is not accessible can still be refered to but it is 
-	 * tagged as being not accessible - the Java builder will create a problem 
-	 * marker for example. The severity of this marker is controled through
-	 * the {@link #COMPILER_PB_FORBIDDEN_REFERENCE} compiler option.
-	 * Note this is different from inclusion and 
-	 * exclusion patterns on source classpath entries, where a source file that
-	 * is excluded is not even compiled.
-	 * When no inclusion patterns are specified, all source and class files
-	 * in the container are initially accessible. On the other hand, specifying one 
-	 * or more inclusion patterns means that all <b>and only</b> source and
-	 * class files matching at least one of the specified patterns are accessible. 
-	 * If exclusion patterns are specified, the initial set of accessible source and 
-	 * class files is then reduced by eliminating source and class files matched 
-	 * by at least one of the exclusion patterns. Inclusion and exclusion 
-	 * patterns look like relative file paths with wildcards and are interpreted 
-	 * relative to each entry's path of the container. Patterns are case-sensitive 
-	 * and they can contain '**', '*' or '?' wildcards (see 
-	 * {@link IClasspathEntry#getExclusionPatterns()} for the full description
-	 * of their syntax and semantics).
+	 * The access rules determine the set of accessible source and class files
+	 * in the container. If the list of access rules is empty, then all files
+	 * in this container are accessible.
+	 * See {@link IAccessRule} for a detailed description of access
+	 * rules. Note that if an entry defined by the container defines access rules,
+	 * then these access rules are combined with the given access rules.
+	 * The given access rules are considered first, then the entry's access rules are 
+	 * considered.
 	 * </p>
 	 * <p>
-	 * For example, if one of the container's entry path is 
-	 * <code>/Project/someLib.jar</code>, there are no inclusion filters, and the
-	 * exclusion pattern is 
-	 * <code>com/xyz/tests/&#42;&#42;</code>, then class files
-	 * like <code>/Project/someLib.jar/com/xyz/Foo.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/utils/Bar.class</code> would be accessible,
-	 * whereas <code>/Project/someLib.jar/com/xyz/tests/T1.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/tests/quick/T2.class</code> would not be
-	 * accessible. 
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.
 	 * </p>
 	 * <p>
 	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
 	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
-	 * If exported, dependent projects will concatenate the inclusion patterns of this entry with the
-	 * inclusion patterns of the projects, and they will concatenate the exclusion patterns of this entry
-	 * with the exclusion patterns of the project. 
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project. 
 	 * </p>
 	 * <p>
 	 * Note that this operation does not attempt to validate classpath containers
@@ -2739,10 +2828,8 @@
 	 * 
 	 * @param containerPath the path identifying the container, it must be formed of at least
 	 * 	one segment (ID+hints)
-	 * @param inclusionPatterns the possibly empty list of inclusion patterns
-	 *    represented as relative paths
-	 * @param exclusionPatterns the possibly empty list of exclusion patterns
-	 *    represented as relative paths
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
 	 * @param isExported a boolean indicating whether this entry is contributed to dependent
 	 *    projects in addition to the output location
 	 * @return a new container classpath entry
@@ -2750,12 +2837,13 @@
 	 * @see JavaCore#getClasspathContainer(IPath, IJavaProject)
 	 * @see JavaCore#setClasspathContainer(IPath, IJavaProject[], IClasspathContainer[], IProgressMonitor)
 	 * @see JavaCore#newContainerEntry(IPath, boolean)
+	 * @see JavaCore#newAccessRule(IPath, int)
 	 * @since 3.1
 	 */	
 	public static IClasspathEntry newContainerEntry(
 			IPath containerPath, 
-			IPath[] inclusionPatterns, 
-			IPath[] exclusionPatterns, 
+			IAccessRule[] accessRules, 
+			IClasspathAttribute[] extraAttributes,
 			boolean isExported) {
 			
 		if (containerPath == null) Assert.isTrue(false, "Container path cannot be null"); //$NON-NLS-1$
@@ -2768,21 +2856,57 @@
 			IPackageFragmentRoot.K_SOURCE,
 			IClasspathEntry.CPE_CONTAINER,
 			containerPath,
-			inclusionPatterns,
-			exclusionPatterns, 
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
 			null, // source attachment
 			null, // source attachment root
 			null, // specific output folder
-			isExported);
+			isExported,
+			accessRules,
+			true, // combine access rules
+			extraAttributes);
 	}	
 	
 	/**
+	 * Creates and returns a type hierarchy for all types in the given
+	 * region, considering subtypes within that region and considering types in the 
+	 * working copies with the given owner. 
+	 * In other words, the owner's working copies will take 
+	 * precedence over their original compilation units in the workspace.
+	 * <p>
+	 * Note that if a working copy is empty, it will be as if the original compilation
+	 * unit had been deleted.
+	 * <p>
+	 *
+	 * @param monitor the given progress monitor
+	 * @param region the given region
+	 * @param owner the owner of working copies that take precedence over their original compilation units,
+	 *   or <code>null</code> if the primary working copy owner should be used
+	 * @exception JavaModelException if an element in the region does not exist or if an
+	 *		exception occurs while accessing its corresponding resource
+	 * @exception IllegalArgumentException if region is <code>null</code>
+	 * @return a type hierarchy for all types in the given
+	 * region, considering subtypes within that region
+	 * @since 3.1
+	 */
+	public static ITypeHierarchy newTypeHierarchy(IRegion region, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
+		if (region == null) {
+			throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
+		}
+		ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+		CreateTypeHierarchyOperation op =
+			new CreateTypeHierarchyOperation(region, workingCopies, null, true/*compute subtypes*/);
+		op.runOperation(monitor);
+		return op.getResult();
+	}
+	
+	/**
 	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_LIBRARY</code> for the 
 	 * JAR or folder identified by the given absolute path. This specifies that all package fragments 
 	 * within the root will have children of type <code>IClassFile</code>.
 	 * This method is fully equivalent to calling
-	 * {@link #newLibraryEntry(IPath, IPath, IPath, IPath[], IPath[], boolean)
-	 * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, new IPath[0], new IPath[0], false)}.
+	 * {@link #newLibraryEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], false)}.
 	 *
 	 * @param path the absolute path of the binary archive
 	 * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, 
@@ -2798,12 +2922,12 @@
 		IPath sourceAttachmentRootPath) {
 			
 		return newLibraryEntry(
-			path,
+			path, 
 			sourceAttachmentPath,
 			sourceAttachmentRootPath,
-			ClasspathEntry.INCLUDE_ALL, 
-			ClasspathEntry.EXCLUDE_NONE, 
-			false);
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
+			false/*not exported*/);
 	}
 
 	/**
@@ -2811,8 +2935,8 @@
 	 * identified by the given absolute path. This specifies that all package fragments within the root 
 	 * will have children of type <code>IClassFile</code>.
 	 * This method is fully equivalent to calling
-	 * {@link #newLibraryEntry(IPath, IPath, IPath, IPath[], IPath[], boolean)
-	 * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, new IPath[0], new IPath[0], isExported)}.
+	 * {@link #newLibraryEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newLibraryEntry(path, sourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
 	 * 
 	 * @param path the absolute path of the binary archive
 	 * @param sourceAttachmentPath the absolute path of the corresponding source archive or folder, 
@@ -2832,11 +2956,11 @@
 		boolean isExported) {
 			
 		return newLibraryEntry(
-			path,
+			path, 
 			sourceAttachmentPath,
 			sourceAttachmentRootPath,
-			ClasspathEntry.INCLUDE_ALL, 
-			ClasspathEntry.EXCLUDE_NONE, 
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
 			isExported);
 	}
 
@@ -2860,46 +2984,22 @@
 	 * Note that this operation does not attempt to validate or access the 
 	 * resources at the given paths.
 	 * <p>
-	 * The inclusion patterns determines the initial set of accessible class files in 
-	 * the library; the exclusion patterns are then used to reduce this
-	 * set. A class file that is not accessible can still be refered to but it is 
-	 * tagged as being not accessible - the Java builder will create a problem 
-	 * marker for example. The severity of this marker is controled through
-	 * the {@link #COMPILER_PB_FORBIDDEN_REFERENCE} compiler option.
-	 * Note this is different from inclusion and 
-	 * exclusion patterns on source classpath entries, where a source file that
-	 * is excluded is not even compiled.
-	 * When no inclusion patterns are specified, all class files
-	 * in the resource tree (or in the jar file) rooted at the library
-	 * entry's path are initially accessible. On the other hand, specifying one 
-	 * or more inclusion patterns means that all <b>and only</b> class 
-	 * files matching at least one of the specified patterns are accessible. 
-	 * If exclusion patterns are specified, the initial set of accessible class files is 
-	 * then reduced by eliminating class files matched by at least one of 
-	 * the exclusion patterns. Inclusion and exclusion patterns look like 
-	 * relative file paths with wildcards and are interpreted relative to the 
-	 * library entry's path. Patterns are case-sensitive and they can 
-	 * contain '**', '*' or '?' wildcards (see 
-	 * {@link IClasspathEntry#getExclusionPatterns()} for the full description
-	 * of their syntax and semantics).
+	 * The access rules determine the set of accessible class files
+	 * in the library. If the list of access rules is empty then all files
+	 * in this library are accessible.
+	 * See {@link IAccessRule} for a detailed description of access
+	 * rules.
 	 * </p>
 	 * <p>
-	 * For example, if the library path is 
-	 * <code>/Project/someLib.jar</code>, there are no inclusion filters, and the
-	 * exclusion pattern is 
-	 * <code>com/xyz/tests/&#42;&#42;</code>, then class files
-	 * like <code>/Project/someLib.jar/com/xyz/Foo.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/utils/Bar.class</code> would be accessible,
-	 * whereas <code>/Project/someLib.jar/com/xyz/tests/T1.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/tests/quick/T2.class</code> would not be
-	 * accessible. 
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.
 	 * </p>
 	 * <p>
 	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
 	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
-	 * If exported, dependent projects will concatenate the inclusion patterns of this entry with the
-	 * inclusion patterns of the projects, and they will concatenate the exclusion patterns of this entry
-	 * with the exclusion patterns of the project. 
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project. 
 	 * </p>
 	 * 
 	 * @param path the absolute path of the binary archive
@@ -2908,10 +3008,10 @@
 	 *   and will be automatically converted to <code>null</code>.
 	 * @param sourceAttachmentRootPath the location of the root within the source archive or folder
 	 *    or <code>null</code> if this location should be automatically detected.
-	 * @param inclusionPatterns the possibly empty list of inclusion patterns
-	 *    represented as relative paths
-	 * @param exclusionPatterns the possibly empty list of exclusion patterns
-	 *    represented as relative paths
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
+	 * @param isExported indicates whether this entry is contributed to dependent
+	 * 	  projects in addition to the output location
 	 * @return a new library classpath entry
 	 * @since 3.1
 	 */
@@ -2919,8 +3019,8 @@
 			IPath path,
 			IPath sourceAttachmentPath,
 			IPath sourceAttachmentRootPath,
-			IPath[] inclusionPatterns, 
-			IPath[] exclusionPatterns, 
+			IAccessRule[] accessRules, 
+			IClasspathAttribute[] extraAttributes,
 			boolean isExported) {
 			
 		if (path == null) Assert.isTrue(false, "Library path cannot be null"); //$NON-NLS-1$
@@ -2938,20 +3038,23 @@
 			IPackageFragmentRoot.K_BINARY,
 			IClasspathEntry.CPE_LIBRARY,
 			JavaProject.canonicalizedPath(path),
-			inclusionPatterns, 
-			exclusionPatterns, 
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
 			sourceAttachmentPath,
 			sourceAttachmentRootPath,
 			null, // specific output folder
-			isExported);
+			isExported,
+			accessRules,
+			false, // no access rules to combine
+			extraAttributes);
 	}
 	
 	/**
 	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_PROJECT</code>
 	 * for the project identified by the given absolute path.
 	 * This method is fully equivalent to calling
-	 * {@link #newProjectEntry(IPath, IPath[], IPath[], boolean)
-	 * newProjectEntry(path, new IPath[0], new IPath[0], false)}.
+	 * {@link #newProjectEntry(IPath, IAccessRule[], boolean, IClasspathAttribute[], boolean)
+	 * newProjectEntry(path, new IAccessRule[0], true, new IClasspathAttribute[0], false)}.
 	 * 
 	 * @param path the absolute path of the binary archive
 	 * @return a new project classpath entry
@@ -2964,8 +3067,8 @@
 	 * Creates and returns a new classpath entry of kind <code>CPE_PROJECT</code>
 	 * for the project identified by the given absolute path.
 	 * This method is fully equivalent to calling
-	 * {@link #newProjectEntry(IPath, IPath[], IPath[], boolean)
-	 * newProjectEntry(path, new IPath[0], new IPath[0], isExported)}.
+	 * {@link #newProjectEntry(IPath, IAccessRule[], boolean, IClasspathAttribute[], boolean)
+	 * newProjectEntry(path, new IAccessRule[0], true, new IClasspathAttribute[0], isExported)}.
 	 * 
 	 * @param path the absolute path of the prerequisite project
 	 * @param isExported indicates whether this entry is contributed to dependent
@@ -2979,8 +3082,9 @@
 		
 		return newProjectEntry(
 			path,
-			ClasspathEntry.INCLUDE_ALL, 
-			ClasspathEntry.EXCLUDE_NONE, 
+			ClasspathEntry.NO_ACCESS_RULES,
+			true,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
 			isExported);
 	}
 
@@ -2999,52 +3103,33 @@
 	 * The prerequisite project is referred to using an absolute path relative to the workspace root.
 	 * </p>
 	 * <p>
-	 * The inclusion patterns determines the initial set of accessible source and class files in 
-	 * the project; the exclusion patterns are then used to reduce this
-	 * set. A source or class file that is not accessible can still be refered to but it is 
-	 * tagged as being not accessible - the Java builder will create a problem 
-	 * marker for example. The severity of this marker is controled through
-	 * the {@link #COMPILER_PB_FORBIDDEN_REFERENCE} compiler option.
-	 * Note this is different from inclusion and 
-	 * exclusion patterns on source classpath entries, where a source file that
-	 * is excluded is not even compiled.
-	 * When no inclusion patterns are specified, all source and class files
-	 * in the project are initially accessible. On the other hand, specifying one 
-	 * or more inclusion patterns means that all <b>and only</b> source and
-	 * class files matching at least one of the specified patterns are accessible. 
-	 * If exclusion patterns are specified, the initial set of accessible source and 
-	 * class files is then reduced by eliminating source and class files matched 
-	 * by at least one of the exclusion patterns. Inclusion and exclusion 
-	 * patterns look like relative file paths with wildcards and are interpreted 
-	 * relative to each entry's path of the project. Patterns are case-sensitive 
-	 * and they can contain '**', '*' or '?' wildcards (see 
-	 * {@link IClasspathEntry#getExclusionPatterns()} for the full description
-	 * of their syntax and semantics).
+	 * The access rules determine the set of accessible class files
+	 * in the project. If the list of access rules is empty then all files
+	 * in this project are accessible.
+	 * See {@link IAccessRule} for a detailed description of access rules.
 	 * </p>
 	 * <p>
-	 * For example, if one of the project's entry path is 
-	 * <code>/Project/someLib.jar</code>, there are no inclusion filters, and the
-	 * exclusion pattern is 
-	 * <code>com/xyz/tests/&#42;&#42;</code>, then class files
-	 * like <code>/Project/someLib.jar/com/xyz/Foo.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/utils/Bar.class</code> would be accessible,
-	 * whereas <code>/Project/someLib.jar/com/xyz/tests/T1.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/tests/quick/T2.class</code> would not be
-	 * accessible. 
+	 * The <code>combineAccessRules</code> flag indicates whether access rules of one (or more)
+	 * exported entry of the project should be combined with the given access rules. If they should
+	 * be combined, the given access rules are considered first, then the entry's access rules are 
+	 * considered.
+	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.
 	 * </p>
 	 * <p>
 	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
 	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
-	 * If exported, dependent projects will concatenate the inclusion patterns of this entry with the
-	 * inclusion patterns of the projects, and they will concatenate the exclusion patterns of this entry
-	 * with the exclusion patterns of the project. 
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project. 
 	 * </p>
 	 * 
 	 * @param path the absolute path of the prerequisite project
-	 * @param inclusionPatterns the possibly empty list of inclusion patterns
-	 *    represented as relative paths
-	 * @param exclusionPatterns the possibly empty list of exclusion patterns
-	 *    represented as relative paths
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param combineAccessRules whether the access rules of the project's exported entries should be combined with the given access rules
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
 	 * @param isExported indicates whether this entry is contributed to dependent
 	 * 	  projects in addition to the output location
 	 * @return a new project classpath entry
@@ -3052,8 +3137,9 @@
 	 */
 	public static IClasspathEntry newProjectEntry(
 			IPath path, 
-			IPath[] inclusionPatterns, 
-			IPath[] exclusionPatterns, 
+			IAccessRule[] accessRules, 
+			boolean combineAccessRules,
+			IClasspathAttribute[] extraAttributes,
 			boolean isExported) {
 		
 		if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
@@ -3062,12 +3148,15 @@
 			IPackageFragmentRoot.K_SOURCE,
 			IClasspathEntry.CPE_PROJECT,
 			path,
-			inclusionPatterns, 
-			exclusionPatterns, 
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
 			null, // source attachment
 			null, // source attachment root
 			null, // specific output folder
-			isExported);
+			isExported,
+			accessRules,
+			combineAccessRules,
+			extraAttributes);
 	}
 
 	/**
@@ -3152,6 +3241,33 @@
 	/**
 	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
 	 * for the project's source folder identified by the given absolute 
+	 * workspace-relative path but excluding all source files with paths
+	 * matching any of the given patterns, and associated with a specific output location
+	 * (that is, ".class" files are not going to the project default output location). 
+	 * <p>
+	 * The convenience method is fully equivalent to:
+	 * <pre>
+	 * newSourceEntry(path, new IPath[] {}, exclusionPatterns, specificOutputLocation, new IClasspathAttribute[] {});
+	 * </pre>
+	 * </p>
+	 *
+	 * @param path the absolute workspace-relative path of a source folder
+	 * @param inclusionPatterns the possibly empty list of inclusion patterns
+	 *    represented as relative paths
+	 * @param exclusionPatterns the possibly empty list of exclusion patterns
+	 *    represented as relative paths
+	 * @param specificOutputLocation the specific output location for this source entry (<code>null</code> if using project default ouput location)
+	 * @return a new source classpath entry
+	 * @see #newSourceEntry(IPath, IPath[], IPath[], IPath, IClasspathAttribute[])
+	 * @since 3.0
+	 */
+	public static IClasspathEntry newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation) {
+		return newSourceEntry(path, inclusionPatterns, exclusionPatterns, specificOutputLocation, ClasspathEntry.NO_EXTRA_ATTRIBUTES);
+	}
+	
+	/**
+	 * Creates and returns a new classpath entry of kind <code>CPE_SOURCE</code>
+	 * for the project's source folder identified by the given absolute 
 	 * workspace-relative path using the given inclusion and exclusion patterns
 	 * to determine which source files are included, and the given output path
 	 * to control the output location of generated files.
@@ -3207,6 +3323,10 @@
 	 * (see <code>JavaCore.newProjectEntry</code>). Particular source entries
 	 * cannot be selectively exported.
 	 * </p>
+	 * <p>
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.
+	 * </p>
 	 *
 	 * @param path the absolute workspace-relative path of a source folder
 	 * @param inclusionPatterns the possibly empty list of inclusion patterns
@@ -3214,13 +3334,14 @@
 	 * @param exclusionPatterns the possibly empty list of exclusion patterns
 	 *    represented as relative paths
 	 * @param specificOutputLocation the specific output location for this source entry (<code>null</code> if using project default ouput location)
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
 	 * @return a new source classpath entry with the given exclusion patterns
 	 * @see IClasspathEntry#getInclusionPatterns()
 	 * @see IClasspathEntry#getExclusionPatterns()
 	 * @see IClasspathEntry#getOutputLocation()
-	 * @since 3.0
+	 * @since 3.1
 	 */
-	public static IClasspathEntry newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation) {
+	public static IClasspathEntry newSourceEntry(IPath path, IPath[] inclusionPatterns, IPath[] exclusionPatterns, IPath specificOutputLocation, IClasspathAttribute[] extraAttributes) {
 
 		if (path == null) Assert.isTrue(false, "Source path cannot be null"); //$NON-NLS-1$
 		if (!path.isAbsolute()) Assert.isTrue(false, "Path for IClasspathEntry must be absolute"); //$NON-NLS-1$
@@ -3236,14 +3357,17 @@
 			null, // source attachment
 			null, // source attachment root
 			specificOutputLocation, // custom output location
-			false);
+			false,
+			null,
+			false, // no access rules to combine
+			extraAttributes); 
 	}
 
 	/**
 	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_VARIABLE</code>
 	 * for the given path. This method is fully equivalent to calling
-	 * {@link #newVariableEntry(IPath, IPath, IPath, IPath[], IPath[], boolean)
-	 * newLibraryEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, new IPath[0], new IPath[0], false)}.
+	 * {@link #newVariableEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], false)}.
 	 * 
 	 * @param variablePath the path of the binary archive; first segment is the
 	 *   name of a classpath variable
@@ -3264,10 +3388,10 @@
 	}
 
 	/**
-	 * Creates and returns a new non-exported classpath entry of kind <code>CPE_VARIABLE</code>
+	 * Creates and returns a new classpath entry of kind <code>CPE_VARIABLE</code>
 	 * for the given path. This method is fully equivalent to calling
-	 * {@link #newVariableEntry(IPath, IPath, IPath, IPath[], IPath[], boolean)
-	 * newLibraryEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, new IPath[0], new IPath[0], false)}.
+	 * {@link #newVariableEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)
+	 * newVariableEntry(variablePath, variableSourceAttachmentPath, sourceAttachmentRootPath, new IAccessRule[0], new IClasspathAttribute[0], isExported)}.
 	 * 
 	 * @param variablePath the path of the binary archive; first segment is the
 	 *   name of a classpath variable
@@ -3290,10 +3414,10 @@
 
 		return newVariableEntry(
 			variablePath,
-			variableSourceAttachmentPath, // source attachment
-			variableSourceAttachmentRootPath, // source attachment root			
-			ClasspathEntry.INCLUDE_ALL, 
-			ClasspathEntry.EXCLUDE_NONE, 
+			variableSourceAttachmentPath,
+			variableSourceAttachmentRootPath,
+			ClasspathEntry.NO_ACCESS_RULES,
+			ClasspathEntry.NO_EXTRA_ATTRIBUTES,
 			isExported);
 	}
 
@@ -3318,45 +3442,21 @@
 	 *      is bound to "c:/eclipse/plugins". The resolved classpath entry is denoting the library "c:/eclipse/plugins/com.example/example.jar"</li>
 	 * </ul>
 	 * <p>
-	 * The inclusion patterns determines the initial set of accessible source and class files in 
-	 * the project or library; the exclusion patterns are then used to reduce this
-	 * set. A source or class file that is not accessible can still be refered to but it is 
-	 * tagged as being not accessible - the Java builder will create a problem 
-	 * marker for example. The severity of this marker is controled through
-	 * the {@link #COMPILER_PB_FORBIDDEN_REFERENCE} compiler option.
-	 * Note this is different from inclusion and 
-	 * exclusion patterns on source classpath entries, where a source file that
-	 * is excluded is not even compiled.
-	 * When no inclusion patterns are specified, all source and class files
-	 * in the project or library are initially accessible. On the other hand, specifying one 
-	 * or more inclusion patterns means that all <b>and only</b> source and
-	 * class files matching at least one of the specified patterns are accessible. 
-	 * If exclusion patterns are specified, the initial set of accessible source and 
-	 * class files is then reduced by eliminating source and class files matched 
-	 * by at least one of the exclusion patterns. Inclusion and exclusion 
-	 * patterns look like relative file paths with wildcards and are interpreted 
-	 * relative to the resolved entry's path. Patterns are case-sensitive 
-	 * and they can contain '**', '*' or '?' wildcards (see 
-	 * {@link IClasspathEntry#getExclusionPatterns()} for the full description
-	 * of their syntax and semantics).
+	 * The access rules determine the set of accessible class files
+	 * in the project or library. If the list of access rules is empty then all files
+	 * in this project or library are accessible.
+	 * See {@link IAccessRule} for a detailed description of access rules.
 	 * </p>
 	 * <p>
-	 * For example, if the resolved entry path is 
-	 * <code>/Project/someLib.jar</code>, there are no inclusion filters, and the
-	 * exclusion pattern is 
-	 * <code>com/xyz/tests/&#42;&#42;</code>, then class files
-	 * like <code>/Project/someLib.jar/com/xyz/Foo.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/utils/Bar.class</code> would be accessible,
-	 * whereas <code>/Project/someLib.jar/com/xyz/tests/T1.class</code>
-	 * and <code>/Project/someLib.jar/com/xyz/tests/quick/T2.class</code> would not be
-	 * accessible. 
+	 * The <code>extraAttributes</code> list contains name/value pairs that must be persisted with
+	 * this entry. If no extra attributes are provided, an empty array must be passed in.
 	 * </p>
 	 * <p>
 	 * The <code>isExported</code> flag indicates whether this entry is contributed to dependent
 	 * projects. If not exported, dependent projects will not see any of the classes from this entry.
-	 * If exported, dependent projects will concatenate the inclusion patterns of this entry with the
-	 * inclusion patterns of the projects, and they will concatenate the exclusion patterns of this entry
-	 * with the exclusion patterns of the project. 
+	 * If exported, dependent projects will concatenate the accessible files patterns of this entry with the
+	 * accessible files patterns of the projects, and they will concatenate the non accessible files patterns of this entry
+	 * with the non accessible files patterns of the project. 
 	 * </p>
 	 * <p>
 	 * Note that this operation does not attempt to validate classpath variables
@@ -3371,10 +3471,8 @@
 	 *    as the one that begins <code>variablePath</code>)
 	 * @param variableSourceAttachmentRootPath the location of the root within the source archive
 	 *    or <code>null</code> if <code>archivePath</code> is also <code>null</code>
-	 * @param inclusionPatterns the possibly empty list of inclusion patterns
-	 *    represented as relative paths
-	 * @param exclusionPatterns the possibly empty list of exclusion patterns
-	 *    represented as relative paths
+	 * @param accessRules the possibly empty list of access rules for this entry
+	 * @param extraAttributes the possibly empty list of extra attributes to persist with this entry
 	 * @param isExported indicates whether this entry is contributed to dependent
 	 * 	  projects in addition to the output location
 	 * @return a new variable classpath entry
@@ -3384,8 +3482,8 @@
 			IPath variablePath,
 			IPath variableSourceAttachmentPath,
 			IPath variableSourceAttachmentRootPath,
-			IPath[] inclusionPatterns, 
-			IPath[] exclusionPatterns, 
+			IAccessRule[] accessRules, 
+			IClasspathAttribute[] extraAttributes,
 			boolean isExported) {
 
 		if (variablePath == null) Assert.isTrue(false, "Variable path cannot be null"); //$NON-NLS-1$
@@ -3399,12 +3497,15 @@
 			IPackageFragmentRoot.K_SOURCE,
 			IClasspathEntry.CPE_VARIABLE,
 			variablePath,
-			inclusionPatterns, 
-			exclusionPatterns, 
+			ClasspathEntry.INCLUDE_ALL, // inclusion patterns
+			ClasspathEntry.EXCLUDE_NONE, // exclusion patterns
 			variableSourceAttachmentPath, // source attachment
 			variableSourceAttachmentRootPath, // source attachment root			
 			null, // specific output folder
-			isExported);
+			isExported,
+			accessRules,
+			false, // no access rules to combine
+			extraAttributes);
 	}	
 	/**
 	 * Removed the given classpath variable. Does nothing if no value was
@@ -3639,8 +3740,12 @@
 				"\n	}\n	invocation stack trace:"); //$NON-NLS-1$
 				new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
 		}
+		
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
+		if (manager.containerPutIfInitializingWithSameEntries(containerPath, affectedProjects, respectiveContainers))
+			return;
 
-		final int projectLength = affectedProjects.length;
+		final int projectLength = affectedProjects.length;	
 		final IJavaProject[] modifiedProjects;
 		System.arraycopy(affectedProjects, 0, modifiedProjects = new IJavaProject[projectLength], 0, projectLength);
 		final IClasspathEntry[][] oldResolvedPaths = new IClasspathEntry[projectLength][];
@@ -3667,10 +3772,10 @@
 			}
 			if (!found){
 				modifiedProjects[i] = null; // filter out this project - does not reference the container path, or isnt't yet Java project
-				JavaModelManager.getJavaModelManager().containerPut(affectedProject, containerPath, newContainer);
+				manager.containerPut(affectedProject, containerPath, newContainer);
 				continue;
 			}
-			IClasspathContainer oldContainer = JavaModelManager.getJavaModelManager().containerGet(affectedProject, containerPath);
+			IClasspathContainer oldContainer = manager.containerGet(affectedProject, containerPath);
 			if (oldContainer == JavaModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
 //				Map previousContainerValues = (Map)JavaModelManager.getJavaModelManager().previousSessionContainers.get(affectedProject);
 //				if (previousContainerValues != null){
@@ -3708,7 +3813,7 @@
 			}
 			remaining++; 
 			oldResolvedPaths[i] = affectedProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
-			JavaModelManager.getJavaModelManager().containerPut(affectedProject, containerPath, newContainer);
+			manager.containerPut(affectedProject, containerPath, newContainer);
 		}
 		
 		if (remaining == 0) return;
@@ -3735,7 +3840,7 @@
 						// force a refresh of the affected project (will compute deltas)
 						affectedProject.setRawClasspath(
 								affectedProject.getRawClasspath(),
-								SetClasspathOperation.REUSE_PATH,
+								SetClasspathOperation.DO_NOT_SET_OUTPUT,
 								progressMonitor,
 								canChangeResources,
 								oldResolvedPaths[i],
@@ -3762,7 +3867,7 @@
 		} finally {
 			for (int i = 0; i < projectLength; i++) {
 				if (respectiveContainers[i] == null) {
-					JavaModelManager.getJavaModelManager().containerPut(affectedProjects[i], containerPath, null); // reset init in progress marker
+					manager.containerPut(affectedProjects[i], containerPath, null); // reset init in progress marker
 				}
 			}
 		}
@@ -3870,8 +3975,9 @@
 	public static void setOptions(Hashtable newOptions) {
 		
 		try {
-			IEclipsePreferences defaultPreferences = getDefaultPreferences();
-			IEclipsePreferences instancePreferences = getInstancePreferences();
+			JavaModelManager manager = JavaModelManager.getJavaModelManager();
+			IEclipsePreferences defaultPreferences = manager.getDefaultPreferences();
+			IEclipsePreferences instancePreferences = manager.getInstancePreferences();
 
 			if (newOptions == null){
 				instancePreferences.clear();
@@ -3893,8 +3999,11 @@
 
 			// persist options
 			instancePreferences.flush();
+			
+			// update cache
+			optionsCache = newOptions==null ? null : new Hashtable(newOptions);
 		} catch (BackingStoreException e) {
-			// fails silently
+			// ignore
 		}
 	}
 
@@ -3947,34 +4056,18 @@
 			// request state folder creation (workaround 19885)
 			JavaCore.getPlugin().getStateLocation();
 
-			// Listen to instance preferences node removal from parent in order to refresh stored one
-			IEclipsePreferences.INodeChangeListener listener = new IEclipsePreferences.INodeChangeListener() {
-				public void added(IEclipsePreferences.NodeChangeEvent event) {
-					// do nothing
-				}
-				public void removed(IEclipsePreferences.NodeChangeEvent event) {
-					if (event.getChild() == preferencesLookup[PREF_INSTANCE]) {
-						preferencesLookup[PREF_INSTANCE] = new InstanceScope().getNode(PLUGIN_ID);
-					}
-				}
-			};
-			((IEclipsePreferences) getInstancePreferences().parent()).addNodeChangeListener(listener);
+			// Initialize eclipse preferences
+			manager.initializePreferences();
 
-			// Listen to default preferences node removal from parent in order to refresh stored one
-			listener = new IEclipsePreferences.INodeChangeListener() {
-				public void added(IEclipsePreferences.NodeChangeEvent event) {
-					// do nothing
-				}
-				public void removed(IEclipsePreferences.NodeChangeEvent event) {
-					if (event.getChild() == preferencesLookup[PREF_DEFAULT]) {
-						preferencesLookup[PREF_DEFAULT] = new DefaultScope().getNode(PLUGIN_ID);
-					}
+			// Listen to preference changes
+			Preferences.IPropertyChangeListener propertyListener = new Preferences.IPropertyChangeListener() {
+				public void propertyChange(Preferences.PropertyChangeEvent event) {
+					JavaCore.optionsCache = null;
 				}
 			};
-			((IEclipsePreferences) getDefaultPreferences().parent()).addNodeChangeListener(listener);
+			JavaCore.getPlugin().getPluginPreferences().addPropertyChangeListener(propertyListener);
 
 			// retrieve variable values
-			getInstancePreferences().addPreferenceChangeListener(new JavaModelManager.EclipsePreferencesListener());
 			manager.loadVariablesAndContainers();
 
 			final IWorkspace workspace = ResourcesPlugin.getWorkspace();
@@ -3990,7 +4083,7 @@
 			
 			// process deltas since last activated in indexer thread so that indexes are up-to-date.
 			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658
-			Job processSavedState = new Job(Util.bind("savedState.jobName")) { //$NON-NLS-1$
+			Job processSavedState = new Job(Messages.savedState_jobName) { 
 				protected IStatus run(IProgressMonitor monitor) {
 					try {
 						// add save participant and process delta atomically
@@ -4022,4 +4115,4 @@
 			throw e;
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java
index a5144b8..5e20900 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaModelException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java
index 66bb9ef..19cac72 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/NamingConventions.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
index 7a2fa00..b8c6ea9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added J2SE 1.5 support
@@ -14,6 +14,7 @@
 import java.util.ArrayList;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.Util;
 
 
 /**
@@ -35,6 +36,10 @@
  * with J2SE 1.4 or earlier, involved only <it>simple</it> signatures.
  * </p>
  * <p>
+ * Note that the "Q" and "!" formats are specific to Eclipse; the remainder
+ * are specified in the JVM spec.
+ * </p>
+ * <p>
  * The syntax for a type signature is:
  * <pre>
  * TypeSignature ::=
@@ -49,6 +54,7 @@
  *   | "Z"  // boolean
  *   | "T" + Identifier + ";" // type variable
  *   | "[" + TypeSignature  // array X[]
+ *   | "!" + TypeSignature  // capture-of ?
  *   | ResolvedClassTypeSignature
  *   | UnresolvedClassTypeSignature
  * 
@@ -208,13 +214,20 @@
 	public static final char C_STAR	= '*';
 	
 	/**
+	 * Character constant indicating an exception in a signature.
+	 * Value is <code>'^'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_EXCEPTION_START	= '^';
+	
+	/**
 	 * Character constant indicating a bound wildcard type argument 
 	 * in a signature with extends clause.
 	 * Value is <code>'+'</code>.
 	 * @since 3.1
 	 */
 	public static final char C_EXTENDS	= '+';
-	
+
 	/**
 	 * Character constant indicating a bound wildcard type argument 
 	 * in a signature with super clause.
@@ -280,12 +293,19 @@
 
 	/**
 	 * Character constant indicating the end of a generic type list in a 
-	 * signature. Value is <code>'%gt;'</code>.
+	 * signature. Value is <code>'&gt;'</code>.
 	 * @since 3.0
 	 */
 	public static final char C_GENERIC_END	= '>';
 
 	/**
+	 * Character constant indicating a capture of a wildcard type in a 
+	 * signature.Value is <code>'!'</code>.
+	 * @since 3.1
+	 */
+	public static final char C_CAPTURE	= '!';
+	
+	/**
 	 * String constant for the signature of the primitive type boolean.
 	 * Value is <code>"Z"</code>.
 	 */
@@ -344,28 +364,42 @@
 	 * @see #getTypeSignatureKind(String)
 	 * @since 3.0
 	 */
-	public static int CLASS_TYPE_SIGNATURE = 1;
+	public static final int CLASS_TYPE_SIGNATURE = 1;
 
 	/**
 	 * Kind constant for a base (primitive or void) type signature.
 	 * @see #getTypeSignatureKind(String)
 	 * @since 3.0
 	 */
-	public static int BASE_TYPE_SIGNATURE = 2;
+	public static final int BASE_TYPE_SIGNATURE = 2;
 
 	/**
 	 * Kind constant for a type variable signature.
 	 * @see #getTypeSignatureKind(String)
 	 * @since 3.0
 	 */
-	public static int TYPE_VARIABLE_SIGNATURE = 3;
+	public static final int TYPE_VARIABLE_SIGNATURE = 3;
 
 	/**
 	 * Kind constant for an array type signature.
 	 * @see #getTypeSignatureKind(String)
 	 * @since 3.0
 	 */
-	public static int ARRAY_TYPE_SIGNATURE = 4;
+	public static final int ARRAY_TYPE_SIGNATURE = 4;
+	
+	/**
+	 * Kind constant for a wildcard type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.1
+	 */
+	public static final int WILDCARD_TYPE_SIGNATURE = 5;
+
+	/**
+	 * Kind constant for the capture of a wildcard type signature.
+	 * @see #getTypeSignatureKind(String)
+	 * @since 3.1
+	 */
+	public static final int CAPTURE_TYPE_SIGNATURE = 6;
 
 	private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
 	private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
@@ -378,6 +412,7 @@
 	private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
 	private static final char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
 	private static final char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
+	private static final char[] CAPTURE = "capture-of".toCharArray(); //$NON-NLS-1$
 	
 	private static final String EMPTY = new String(CharOperation.NO_CHAR);
 		
@@ -705,14 +740,6 @@
 			    return pos;
 			}
 		    break;
-		case 'c':
-		    checkPos = checkName(CHAR, typeName, pos, length);
-		    if (checkPos > 0) {
-		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
-			    buffer.append(C_CHAR);
-			    return pos;
-			} 
-		    break;
 		case 'd':
 		    checkPos = checkName(DOUBLE, typeName, pos, length);
 		    if (checkPos > 0) {
@@ -761,6 +788,25 @@
 			    return pos;
 			}
 		    break;
+		case 'c':
+		    checkPos = checkName(CHAR, typeName, pos, length);
+		    if (checkPos > 0) {
+		        pos = encodeArrayDimension(typeName, checkPos, length, buffer);
+			    buffer.append(C_CHAR);
+			    return pos;
+			} else {
+				checkPos = checkName(CAPTURE, typeName, pos, length);
+				if (checkPos > 0) {
+					pos = consumeWhitespace(typeName, checkPos, length);
+					if (typeName[pos] != '?') {
+						break;
+					}
+				} else {
+					break;
+				}
+			}
+			buffer.append(C_CAPTURE);
+			// fall-thru for wildcard part of capture typecheckPos
 		case '?':
 			// wildcard
 			pos = consumeWhitespace(typeName, pos+1, length);
@@ -940,7 +986,7 @@
 			if (methodSignature[i] == C_PARAM_END) {
 				return count;
 			}
-			int e= scanTypeSignature(methodSignature, i);
+			int e= Util.scanTypeSignature(methodSignature, i);
 			if (e < 0) {
 				throw new IllegalArgumentException();
 			} else {
@@ -959,7 +1005,8 @@
  * @param typeSignature the type signature string
  * @return the kind of type signature; one of the kind constants:
  * {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
- * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE}
+ * {@link #BASE_TYPE_SIGNATURE}, {@link #TYPE_VARIABLE_SIGNATURE}
+ * or {@link #WILDCARD_TYPE_SIGNATURE}
  * @exception IllegalArgumentException if this is not a type signature
  * @since 3.0
  */
@@ -987,6 +1034,12 @@
 		case C_SHORT :
 		case C_VOID :
 			return BASE_TYPE_SIGNATURE;
+		case C_STAR :
+		case C_SUPER :
+		case C_EXTENDS :
+			return WILDCARD_TYPE_SIGNATURE;
+		case C_CAPTURE :
+			return CAPTURE_TYPE_SIGNATURE;
 		default :
 			throw new IllegalArgumentException();
 	}
@@ -1026,299 +1079,18 @@
 		case C_SHORT :
 		case C_VOID :
 			return BASE_TYPE_SIGNATURE;
+		case C_STAR :
+		case C_SUPER :
+		case C_EXTENDS :
+			return WILDCARD_TYPE_SIGNATURE;
+		case C_CAPTURE :
+			return CAPTURE_TYPE_SIGNATURE;			
 		default :
 			throw new IllegalArgumentException();
 	}
 }
 
 /**
- * Scans the given string for a type signature starting at the given index
- * and returns the index of the last character.
- * <pre>
- * TypeSignature:
- *  |  BaseTypeSignature
- *  |  ArrayTypeSignature
- *  |  ClassTypeSignature
- *  |  TypeVariableSignature
- * </pre>
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not a type signature
- * @see #appendTypeSignature(char[], int, boolean, StringBuffer)
- */
-private static int scanTypeSignature(char[] string, int start) {
-	// need a minimum 1 char
-	if (start >= string.length) {
-		throw new IllegalArgumentException();
-	}
-	char c = string[start];
-	switch (c) {
-		case C_ARRAY :
-			return scanArrayTypeSignature(string, start);
-		case C_RESOLVED :
-		case C_UNRESOLVED :
-			return scanClassTypeSignature(string, start);
-		case C_TYPE_VARIABLE :
-			return scanTypeVariableSignature(string, start);
-		case C_BOOLEAN :
-		case C_BYTE :
-		case C_CHAR :
-		case C_DOUBLE :
-		case C_FLOAT :
-		case C_INT :
-		case C_LONG :
-		case C_SHORT :
-		case C_VOID :
-			return scanBaseTypeSignature(string, start);
-		default :
-			throw new IllegalArgumentException();
-	}
-}
-
-/**
- * Scans the given string for a base type signature starting at the given index
- * and returns the index of the last character.
- * <pre>
- * BaseTypeSignature:
- *     <b>B</b> | <b>C</b> | <b>D</b> | <b>F</b> | <b>I</b>
- *   | <b>J</b> | <b>S</b> | <b>V</b> | <b>Z</b>
- * </pre>
- * Note that although the base type "V" is only allowed in method return types,
- * there is no syntactic ambiguity. This method will accept them anywhere
- * without complaint.
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not a base type signature
- */
-private static int scanBaseTypeSignature(char[] string, int start) {
-	// need a minimum 1 char
-	if (start >= string.length) {
-		throw new IllegalArgumentException();
-	}
-	char c = string[start];
-	if ("BCDFIJSVZ".indexOf(c) >= 0) { //$NON-NLS-1$
-		return start;
-	} else {
-		throw new IllegalArgumentException();
-	}
-}
-
-/**
- * Scans the given string for an array type signature starting at the given
- * index and returns the index of the last character.
- * <pre>
- * ArrayTypeSignature:
- *     <b>[</b> TypeSignature
- * </pre>
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not an array type signature
- * @see #appendArrayTypeSignature(char[], int, boolean, StringBuffer)
- */
-private static int scanArrayTypeSignature(char[] string, int start) {
-	// need a minimum 2 char
-	if (start >= string.length - 1) {
-		throw new IllegalArgumentException();
-	}
-	char c = string[start];
-	if (c != C_ARRAY) { //$NON-NLS-1$
-		throw new IllegalArgumentException();
-	}
-	return scanTypeSignature(string, start + 1);
-}
-
-/**
- * Scans the given string for a type variable signature starting at the given
- * index and returns the index of the last character.
- * <pre>
- * TypeVariableSignature:
- *     <b>T</b> Identifier <b>;</b>
- * </pre>
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not a type variable signature
- */
-private static int scanTypeVariableSignature(char[] string, int start) {
-	// need a minimum 3 chars "Tx;"
-	if (start >= string.length - 2) { 
-		throw new IllegalArgumentException();
-	}
-	// must start in "T"
-	char c = string[start];
-	if (c != C_TYPE_VARIABLE) {
-		throw new IllegalArgumentException();
-	}
-	int id = scanIdentifier(string, start + 1);
-	c = string[id + 1];
-	if (c == C_SEMICOLON) {
-		return id + 1;
-	} else {
-		throw new IllegalArgumentException();
-	}
-}
-
-/**
- * Scans the given string for an identifier starting at the given
- * index and returns the index of the last character. 
- * Stop characters are: ";", ":", "&lt;", "&gt;", "/", ".".
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not an identifier
- */
-private static int scanIdentifier(char[] string, int start) {
-	// need a minimum 1 char
-	if (start >= string.length) { 
-		throw new IllegalArgumentException();
-	}
-	int p = start;
-	while (true) {
-		char c = string[p];
-		if (c == '<' || c == '>' || c == ':' || c == ';' || c == '.' || c == '/') {
-			return p - 1;
-		}
-		p++;
-		if (p == string.length) {
-			return p - 1;
-		}
-	}
-}
-
-/**
- * Scans the given string for a class type signature starting at the given
- * index and returns the index of the last character.
- * <pre>
- * ClassTypeSignature:
- *     { <b>L</b> | <b>Q</b> } Identifier
- *           { { <b>/</b> | <b>.</b> Identifier [ <b>&lt;</b> TypeArgumentSignature* <b>&gt;</b> ] }
- *           <b>;</b>
- * </pre>
- * Note that although all "/"-identifiers most come before "."-identifiers,
- * there is no syntactic ambiguity. This method will accept them without
- * complaint.
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not a class type signature
- * @see #appendClassTypeSignature(char[], int, boolean, StringBuffer)
- */
-private static int scanClassTypeSignature(char[] string, int start) {
-	// need a minimum 3 chars "Lx;"
-	if (start >= string.length - 2) { 
-		throw new IllegalArgumentException();
-	}
-	// must start in "L" or "Q"
-	char c = string[start];
-	if (c != C_RESOLVED && c != C_UNRESOLVED) {
-		return -1;
-	}
-	int p = start + 1;
-	while (true) {
-		if (p >= string.length) {
-			throw new IllegalArgumentException();
-		}
-		c = string[p];
-		if (c == C_SEMICOLON) {
-			// all done
-			return p;
-		} else if (c == C_GENERIC_START) {
-			int e = scanTypeArgumentSignatures(string, p);
-			p = e;
-		} else if (c == C_DOT || c == '/') {
-			int id = scanIdentifier(string, p + 1);
-			p = id;
-		}
-		p++;
-	}
-}
-
-/**
- * Scans the given string for a list of type argument signatures starting at
- * the given index and returns the index of the last character.
- * <pre>
- * TypeArgumentSignatures:
- *     <b>&lt;</b> TypeArgumentSignature* <b>&gt;</b>
- * </pre>
- * Note that although there is supposed to be at least one type argument, there
- * is no syntactic ambiguity if there are none. This method will accept zero
- * type argument signatures without complaint.
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not a list of type arguments
- * signatures
- * @see #appendTypeArgumentSignatures(char[], int, boolean, StringBuffer)
- */
-private static int scanTypeArgumentSignatures(char[] string, int start) {
-	// need a minimum 2 char "<>"
-	if (start >= string.length - 1) {
-		throw new IllegalArgumentException();
-	}
-	char c = string[start];
-	if (c != C_GENERIC_START) {
-		throw new IllegalArgumentException();
-	}
-	int p = start + 1;
-	while (true) {
-		if (p >= string.length) {
-			throw new IllegalArgumentException();
-		}
-		c = string[p];
-		if (c == C_GENERIC_END) {
-			return p;
-		}
-		int e = scanTypeArgumentSignature(string, p);
-		p = e + 1;
-	}
-}
-
-/**
- * Scans the given string for a type argument signature starting at the given
- * index and returns the index of the last character.
- * <pre>
- * TypeArgumentSignature:
- *     <b>&#42;</b>
- *  |  <b>+</b> TypeSignature
- *  |  <b>-</b> TypeSignature
- *  |  TypeSignature
- * </pre>
- * Note that although base types are not allowed in type arguments, there is
- * no syntactic ambiguity. This method will accept them without complaint.
- * 
- * @param string the signature string
- * @param start the 0-based character index of the first character
- * @return the 0-based character index of the last character
- * @exception IllegalArgumentException if this is not a type argument signature
- * @see #appendTypeArgumentSignature(char[], int, boolean, StringBuffer)
- */
-private static int scanTypeArgumentSignature(char[] string, int start) {
-	// need a minimum 1 char
-	if (start >= string.length) {
-		throw new IllegalArgumentException();
-	}
-	char c = string[start];
-	if (c == C_STAR) {
-		return start;
-	}
-	if (c == '+' || c == '-') {
-		return scanTypeSignature(string, start + 1);
-	} else {
-		return scanTypeSignature(string, start);
-	}
-}
-
-/**
  * Returns the number of parameter types in the given method signature.
  *
  * @param methodSignature the method signature
@@ -1359,7 +1131,7 @@
 			if (methodSignature[i] == C_PARAM_END) {
 				return result;
 			}
-			int e = scanTypeSignature(methodSignature, i);
+			int e = Util.scanTypeSignature(methodSignature, i);
 			if (e < 0) {
 				throw new IllegalArgumentException();
 			}
@@ -1411,19 +1183,29 @@
  */
 public static char[][] getThrownExceptionTypes(char[] methodSignature) throws IllegalArgumentException {
 	// skip type parameters
-	int paren = CharOperation.lastIndexOf(C_PARAM_END, methodSignature);
-	if (paren == -1) {
+	int exceptionStart = CharOperation.indexOf(C_EXCEPTION_START, methodSignature);
+	if (exceptionStart == -1) {
+		int paren = CharOperation.lastIndexOf(C_PARAM_END, methodSignature);
+		if (paren == -1) {
+			throw new IllegalArgumentException();
+		}
+		// ignore return type
+		exceptionStart = Util.scanTypeSignature(methodSignature, paren+1) + 1;
+		int length = methodSignature.length;
+		if (exceptionStart == length) return CharOperation.NO_CHAR_CHAR;
 		throw new IllegalArgumentException();
 	}
-	// ignore return type
-	int exceptionStart = scanTypeSignature(methodSignature, paren+1) + 1;
 	int length = methodSignature.length;
-	if (exceptionStart == length) return CharOperation.NO_CHAR_CHAR;
-	
-	ArrayList exceptionList = new ArrayList(1);
 	int i = exceptionStart;
+	ArrayList exceptionList = new ArrayList(1);
 	while (i < length) {
-		i = scanTypeSignature(methodSignature, i) + 1;
+		if (methodSignature[i] == C_EXCEPTION_START) {
+			exceptionStart++;
+			i++;
+		} else {
+			throw new IllegalArgumentException();			
+		}
+		i = Util.scanTypeSignature(methodSignature, i) + 1;
 		exceptionList.add(CharOperation.subarray(methodSignature, exceptionStart,i));	
 		exceptionStart = i;
 	}
@@ -1474,7 +1256,7 @@
 			args.toArray(result);
 			return result;
 		}
-		int e = scanTypeArgumentSignature(parameterizedTypeSignature, p);
+		int e = Util.scanTypeArgumentSignature(parameterizedTypeSignature, p);
 		args.add(CharOperation.subarray(parameterizedTypeSignature, p, e+1));
 		p = e + 1;
 	}
@@ -1590,7 +1372,7 @@
 				if (methodOrTypeSignature[i] == ':') {
 					continue nextBound; // empty bound
 				}
-				i = scanTypeSignature(methodOrTypeSignature, i);
+				i = Util.scanTypeSignature(methodOrTypeSignature, i);
 				i++; // position at start of next param if any
 			}
 			paramList.add(CharOperation.subarray(methodOrTypeSignature, paramStart, i));
@@ -1781,7 +1563,7 @@
 		throw new IllegalArgumentException();
 	}
 	// there could be thrown exceptions behind, thus scan one type exactly
-	int last = scanTypeSignature(methodSignature, paren+1);
+	int last = Util.scanTypeSignature(methodSignature, paren+1);
 	return CharOperation.subarray(methodSignature, paren + 1, last+1);
 }
 /**
@@ -2042,20 +1824,20 @@
 	int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1;
 	int depth = 0;
 	if (name[start] == '?') { // wildcard
-		buffer.append("? "); //$NON-NLS-1$
+		buffer.append("?"); //$NON-NLS-1$
 		int index = consumeWhitespace(name, start+1, end+1);
 		switch (name[index]) {
 			case 'e' :
 				int checkPos = checkName(EXTENDS, name, index, end);
 			    if (checkPos > 0) {
-			        buffer.append(EXTENDS).append(' ');
+			        buffer.append(' ').append(EXTENDS).append(' ');
 			        index = consumeWhitespace(name, checkPos, end+1);
 				}
 				break;
 			case 's' :
 				checkPos = checkName(SUPER, name, index, end+1);
 			    if (checkPos > 0) {
-			        buffer.append(SUPER).append(' ');
+			        buffer.append(' ').append(SUPER).append(' ');
 			        index = consumeWhitespace(name, checkPos, end+1);
 				}
 				break;
@@ -2197,6 +1979,77 @@
 public static String[] getSimpleNames(String name) {
 	return CharOperation.toStrings(getSimpleNames(name.toCharArray()));
 }
+
+	
+/**
+ * Returns a method signature with any capture information removed. 
+ * Returns the method signature itself if no capture information is
+ * present.
+ * <p>
+ * For example (using equivalent string-based method):
+ * <pre>
+ * <code>
+ * removeCaptureFromMethod("LTest<!+Ljava.lang.Throwable;>;")
+ * will return: "LTest<+Ljava.lang.Throwable;>;"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param captureSignature the signature which may have been captured
+ * @return new signature without capture information or siganture itself
+ * 	if no specific capture information was there
+ * @exception NullPointerException if <code>captureSignature</code> is null
+ * @since 3.1
+ * TODO (frederic) Create remove(char[], char) method on CharOperation and call it from here
+ */
+public static char[] removeCaptureFromMethod(char[] captureSignature) {
+		
+	char[] result = null;
+	int count = 0;
+	for (int i = 0, length = captureSignature.length; i < length; i++) {
+		char c = captureSignature[i];
+		if (c == C_CAPTURE) {
+			if (result == null) {
+				result = new char[length];
+				System.arraycopy(captureSignature, 0, result, 0, i);
+				count = i;
+			}
+		} else if (result != null) {
+			result[count++] = c;
+		}
+	}
+	if (result == null) return captureSignature;
+	System.arraycopy(result, 0, result = new char[count], 0, count);
+	return result;
+}
+	
+/**
+ * Returns a method signature with any capture information removed. 
+ * Returns the method signature itself if no capture information is
+ * present.
+ * <p>
+ * For example:
+ * <pre>
+ * <code>
+ * removeCaptureFromMethod("LTest<!+Ljava.lang.Throwable;>;")
+ * will return: "LTest<+Ljava.lang.Throwable;>;"
+ * </code>
+ * </pre>
+ * </p>
+ *
+ * @param captureSignature the signature which may have been captured
+ * @return new signature without capture information or siganture itself
+ * 	if no specific capture information was there
+ * @exception NullPointerException if <code>captureSignature</code> is null
+ * @since 3.1
+ */
+public static String removeCaptureFromMethod(String captureSignature) {
+		char[] array = captureSignature.toCharArray();
+		char[] result = removeCaptureFromMethod(array);
+		if (array == result) return captureSignature;
+		return new String(result);
+}
+
 /**
  * Converts the given method signature to a readable form. The method signature is expected to
  * be dot-based.
@@ -2351,7 +2204,7 @@
  * @param buffer the string buffer to append to
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not a type signature
- * @see #scanTypeSignature(char[], int)
+ * @see Util#scanTypeSignature(char[], int)
  */
 private static int appendTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
 	return appendTypeSignature(string, start, fullyQualifyTypeNames, buffer, false);
@@ -2371,7 +2224,7 @@
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not a type signature, or if isVarArgs is <code>true</code>,
  * and the type is not an array type signature.
- * @see #scanTypeSignature(char[], int)
+ * @see Util#scanTypeSignature(char[], int)
  */
 private static int appendTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) {
 	// need a minimum 1 char
@@ -2398,6 +2251,7 @@
 			case C_STAR:
 			case C_EXTENDS:
 			case C_SUPER:
+			case C_CAPTURE:
 			default:
 				throw new IllegalArgumentException(); // a var args is an array type
 		}
@@ -2409,8 +2263,8 @@
 			case C_UNRESOLVED :
 				return appendClassTypeSignature(string, start, fullyQualifyTypeNames, buffer);
 			case C_TYPE_VARIABLE :
-				int e = scanTypeVariableSignature(string, start);
-				buffer.append(CharOperation.subarray(string, start + 1, e));
+				int e = Util.scanTypeVariableSignature(string, start);
+				buffer.append(string, start + 1, e - start - 1);
 				return e;
 			case C_BOOLEAN :
 				buffer.append(BOOLEAN);
@@ -2439,6 +2293,8 @@
 			case C_VOID :
 				buffer.append(VOID);
 				return start;
+			case C_CAPTURE :
+				return appendCaptureTypeSignature(string, start, fullyQualifyTypeNames, buffer);
 			case C_STAR:
 			case C_EXTENDS:
 			case C_SUPER:
@@ -2459,7 +2315,7 @@
  *   qualified, and <code>false</code> to use only simple names
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not an array type signature
- * @see #scanArrayTypeSignature(char[], int)
+ * @see Util#scanArrayTypeSignature(char[], int)
  */
 private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
 	return appendArrayTypeSignature(string, start, fullyQualifyTypeNames, buffer, false);
@@ -2473,11 +2329,37 @@
  * @param start the 0-based character index of the first character
  * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
  *   qualified, and <code>false</code> to use only simple names
+ * @return the 0-based character index of the last character
+ * @exception IllegalArgumentException if this is not an array type signature
+ * @see Util#scanArrayTypeSignature(char[], int)
+ */
+private static int appendCaptureTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
+	// need a minimum 2 char
+	if (start >= string.length - 1) {
+		throw new IllegalArgumentException();
+	}
+	char c = string[start];
+	if (c != C_CAPTURE) { //$NON-NLS-1$
+		throw new IllegalArgumentException();
+	}
+	buffer.append(CAPTURE).append(' ');
+	return appendTypeArgumentSignature(string, start + 1, fullyQualifyTypeNames, buffer);
+}
+
+/**
+ * Scans the given string for an array type signature starting at the given
+ * index and appends it to the given buffer, and returns the index of the last
+ * character.
+ * 
+ * @param string the signature string
+ * @param start the 0-based character index of the first character
+ * @param fullyQualifyTypeNames <code>true</code> if type names should be fully
+ *   qualified, and <code>false</code> to use only simple names
  * @param isVarArgs <code>true</code> if the array type must be displayed as a
  * variable argument, <code>false</code> otherwise
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not an array type signature
- * @see #scanArrayTypeSignature(char[], int)
+ * @see Util#scanArrayTypeSignature(char[], int)
  */
 private static int appendArrayTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer, boolean isVarArgs) {
 	// need a minimum 2 char
@@ -2508,7 +2390,7 @@
  * @param buffer the string buffer to append to
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not a class type signature
- * @see #scanClassTypeSignature(char[], int)
+ * @see Util#scanClassTypeSignature(char[], int)
  */
 private static int appendClassTypeSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
 	// need a minimum 3 chars "Lx;"
@@ -2592,7 +2474,7 @@
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not a list of type argument
  * signatures
- * @see #scanTypeArgumentSignatures(char[], int)
+ * @see Util#scanTypeArgumentSignatures(char[], int)
  */
 private static int appendTypeArgumentSignatures(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
 	// need a minimum 2 char "<>"
@@ -2636,7 +2518,7 @@
  * @param buffer the string buffer to append to
  * @return the 0-based character index of the last character
  * @exception IllegalArgumentException if this is not a type argument signature
- * @see #scanTypeArgumentSignature(char[], int)
+ * @see Util#scanTypeArgumentSignature(char[], int)
  */
 private static int appendTypeArgumentSignature(char[] string, int start, boolean fullyQualifyTypeNames, StringBuffer buffer) {
 	// need a minimum 1 char
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
index 3769c0e..899f8ac 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ToolFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -338,5 +338,53 @@
 		scanner = new PublicScanner(tokenizeComments, tokenizeWhiteSpace, false/*nls*/,level /*sourceLevel*/, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
 		scanner.recordLineSeparator = recordLineSeparator;
 		return scanner;
-	}	
+	}
+
+	/**
+	 * Create a scanner, indicating the level of detail requested for tokenizing. The scanner can then be
+	 * used to tokenize some source in a Java aware way.
+	 * Here is a typical scanning loop:
+	 * 
+	 * <code>
+	 * <pre>
+	 *   IScanner scanner = ToolFactory.createScanner(false, false, false, false);
+	 *   scanner.setSource("int i = 0;".toCharArray());
+	 *   while (true) {
+	 *     int token = scanner.getNextToken();
+	 *     if (token == ITerminalSymbols.TokenNameEOF) break;
+	 *     System.out.println(token + " : " + new String(scanner.getCurrentTokenSource()));
+	 *   }
+	 * </pre>
+	 * </code>
+	 * 
+	 * <p>
+	 * The returned scanner will tolerate unterminated line comments (missing line separator). It can be made stricter
+	 * by using API with extra boolean parameter (<code>strictCommentMode</code>).
+	 * <p>
+	 * @param tokenizeComments if set to <code>false</code>, comments will be silently consumed
+	 * @param tokenizeWhiteSpace if set to <code>false</code>, white spaces will be silently consumed,
+	 * @param recordLineSeparator if set to <code>true</code>, the scanner will record positions of encountered line 
+	 * separator ends. In case of multi-character line separators, the last character position is considered. These positions
+	 * can then be extracted using <code>IScanner#getLineEnds</code>. Only non-unicode escape sequences are 
+	 * considered as valid line separators.
+	 * @param sourceLevel if set to <code>&quot;1.3&quot;</code> or <code>null</code>, occurrences of 'assert' will be reported as identifiers
+	 * (<code>ITerminalSymbols#TokenNameIdentifier</code>), whereas if set to <code>&quot;1.4&quot;</code>, it
+	 * would report assert keywords (<code>ITerminalSymbols#TokenNameassert</code>). Java 1.4 has introduced
+	 * a new 'assert' keyword.
+	 * @param complianceLevel This is used to support the Unicode 4.0 character sets. if set to 1.5 or above,
+	 * the Unicode 4.0 is supporte, otherwise Unicode 3.0 is supported.
+  	 * @return a scanner
+	 * @see org.eclipse.jdt.core.compiler.IScanner
+     * @since 3.0
+	 */
+	public static IScanner createScanner(boolean tokenizeComments, boolean tokenizeWhiteSpace, boolean recordLineSeparator, String sourceLevel, String complianceLevel) {
+		PublicScanner scanner = null;
+		long sourceLevelValue = CompilerOptions.versionToJdkLevel(sourceLevel);
+		if (sourceLevelValue == 0) sourceLevelValue = ClassFileConstants.JDK1_3; // fault-tolerance
+		long complianceLevelValue = CompilerOptions.versionToJdkLevel(complianceLevel);
+		if (complianceLevelValue == 0) complianceLevelValue = ClassFileConstants.JDK1_3; // fault-tolerance
+		scanner = new PublicScanner(tokenizeComments, tokenizeWhiteSpace, false/*nls*/,sourceLevelValue /*sourceLevel*/, complianceLevelValue, null/*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
+		scanner.recordLineSeparator = recordLineSeparator;
+		return scanner;
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java
index f1216bb..24e5ece 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/WorkingCopyOwner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,7 +21,7 @@
  * they can pass in to various APIs (e.g. <code>IType.resolveType(String, WorkingCopyOwner)</code>.
  * Clients can also override the default implementation of <code>createBuffer(ICompilationUnit)</code>.
  * </p><p>
- * Note: even though this class has no abstract method, which means that it provides functional default behvior,
+ * Note: even though this class has no abstract method, which means that it provides functional default behavior,
  * it is still an abstract class, as clients are intended to own their owner implementation.
  * </p>
  * @see ICompilationUnit#becomeWorkingCopy(IProblemRequestor, org.eclipse.core.runtime.IProgressMonitor)
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java
index 4f59b1e..2036684 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/IScanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java
index fe192f6..3cdf047 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/compiler/ITerminalSymbols.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -152,4 +152,14 @@
      * @since 3.0
      */
 	int TokenNameELLIPSIS = 402;
+	
+	/**
+	 * @since 3.1
+	 */
+	int TokenNameconst = 403;
+	
+	/**
+	 * @since 3.1
+	 */
+	int TokenNamegoto = 404;
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java
index 68e2c92..03bba9c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/ICodeSnippetRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
index 12e605f..3d1f839 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IEvaluationContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java
index f3f97ef..5195648 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/eval/IGlobalVariable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java
index ff0316f..f8ba578 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
index c2d4a48..0840191 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/DOMFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java
index bda134d..cb2dfc2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMCompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java
index 4f3a854..f4eedbf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java
index ac9de34..2ec880d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
index 317a625..015b526 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMImport.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java
index a7ab013..bb9b028 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java
index bf0aeaa..a031200 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMember.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java
index 0189307..c1f3fc7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java
index 2e4eedd..525105d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMNode.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java
index b6f3f64..674cb0d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMPackage.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java
index f190d9a..9e559a7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/jdom/IDOMType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java
index 3acf28f..7689012 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ByteCodeVisitorAdapter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java
index 77282e4..2453dcd 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFileBytesDisassembler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -34,7 +34,13 @@
 	 * any further information that would be useful for debugging purpose.
 	 * @since 3.1
 	 */
-	public final static int SYSTEM = 3;
+	public final static int SYSTEM = 4;
+	
+	/**
+	 * This mode is used to compact the class name to a simple name instead of a qualified name.
+	 * @since 3.1
+	 */
+	public final static int COMPACT = 8;
 
 	/**
 	 * Answers back the disassembled string of the classfile bytes using the default
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java
index 2dac04d..a76ac8d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ClassFormatException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
index f3d9718..bbbfc65 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/CompilationUnitSorter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -83,7 +83,7 @@
 	 * ordered list of character-based source positions within the compilation
 	 * unit's source code string. Upon return from this method, the positions in
 	 * the array reflect the corresponding new locations in the modified source
-	 * code string, Note that this operation modifies the given array in place.
+	 * code string. Note that this operation modifies the given array in place.
 	 * </p>
 	 * <p>
 	 * The <code>compare</code> method of the given comparator is passed pairs
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java
index 8eb9d87..c7fe6f9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java
index e2c114e..1e1bd2b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
index abf11f4..69d85d0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationComponentValue.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -87,16 +87,18 @@
 	int ARRAY_TAG = '[';
 	
 	/**
-	 * Answer back the annotation component values as described in the JVM specifications.
-	 * This is initialized only if the tag item is '['.
+	 * Returns the annotation component values as described in the JVM specifications
+	 * if the tag item is '['.
+	 * Returns null otherwise.
 	 * 
 	 * @return the annotation component values
 	 */
 	IAnnotationComponentValue[] getAnnotationComponentValues();
 	
 	/**
-	 * Answer back the annotation value as described in the JVM specifications.
-	 * This is initialized only if the tag item is '&#064;'.
+	 * Returns the annotation value as described in the JVM specifications
+	 * if the tag item is '&#064;'.
+	 * Returns null otherwise.
 	 * 
 	 * @return the attribute value
 	 * @since 3.1
@@ -104,53 +106,46 @@
 	IAnnotation getAnnotationValue();
 
 	/**
-	 * Answer back the annotation value as described in the JVM specifications.
-	 * This is initialized only if the tag item is '&#064;'.
-	 * 
-	 * @return the attribute value
-	 * TODO (olivier) remove after 3.1M4
-	 * @deprecated Use getAnnotationValue() instead
-	 */
-	IAnnotation getAttributeValue();
-
-	/**
-	 * Answer back the class info as described in the JVM specifications.
-	 * This is initialized only if the tag item is 'c'.
+	 * Returns the class info as described in the JVM specifications
+	 * if the tag item is 'c'.
+	 * Returns null otherwise.
 	 * 
 	 * @return the class info
 	 */
 	IConstantPoolEntry getClassInfo();
 
 	/**
-	 * Answer back the class info index as described in the JVM specifications.
-	 * This is initialized only if the tag item is 'c'.
+	 * Returns the class info index as described in the JVM specifications
+	 * if the tag item is 'c'.
+	 * Returns null otherwise.
 	 * 
 	 * @return the class info index
 	 */
 	int getClassInfoIndex();
 
 	/**
-	 * Answer back the constant value as described in the JVM specifications.
-	 * This is initialized only if the tag item is one of 'B', 'C', 'D', 'F',
-	 * 'I', 'J', 'S', 'Z', or 's'.
+	 * Returns the constant value as described in the JVM specifications
+	 * if the tag item is one of 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', or 's'.
+	 * Returns null otherwise.
 	 * 
 	 * @return the constant value
 	 */
 	IConstantPoolEntry getConstantValue();
 
 	/**
-	 * Answer back the constant value index as described in the JVM specifications.
-	 * This is initialized only if the tag item is one of 'B', 'C', 'D', 'F',
-	 * 'I', 'J', 'S', 'Z', or 's'.
-	 * 
+	 * Returns the constant value index as described in the JVM specifications
+	 * if the tag item is one of 'B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', or 's'.
+	 * The value is unspecified otherwise.
+	 *
 	 * @return the constant value index
 	 */
 	int getConstantValueIndex();
 
 	/**
-	 * Answer back the simple name of the enum constant represented
-	 * by this annotation component value as described in the JVM specifications.
-	 * This is initialized only if the tag item is 'e'.
+	 * Returns the simple name of the enum constant represented
+	 * by this annotation component value as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * Returns null otherwise.
 	 * 
 	 * @return the enum constant
 	 * @since 3.1
@@ -158,8 +153,9 @@
 	char[] getEnumConstantName();	
 	
 	/**
-	 * Answer back the utf8 constant index as described in the JVM specifications.
-	 * This is initialized only if the tag item is 'e'.
+	 * Returns the utf8 constant index as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the enum constant index
 	 * @since 3.1
@@ -167,9 +163,10 @@
 	int getEnumConstantNameIndex();
 
 	/**
-	 * Answer back the binary name of the type of the enum constant represented
-	 * by this annotation component value as described in the JVM specifications.
-	 * This is initialized only if the tag item is 'e'.
+	 * Returns the binary name of the type of the enum constant represented
+	 * by this annotation component value as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * Returns null otherwise.
 	 * 
 	 * @return the enum constant
 	 * @since 3.1
@@ -177,8 +174,9 @@
 	char[] getEnumConstantTypeName();	
 	
 	/**
-	 * Answer back the utf8 constant index as described in the JVM specifications.
-	 * This is initialized only if the tag item is 'e'.
+	 * Returns the utf8 constant index as described in the JVM specifications
+	 * if the tag item is 'e'.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the enum constant index
 	 * @since 3.1
@@ -186,15 +184,16 @@
 	int getEnumConstantTypeNameIndex();
 
 	/**
-	 * Answer back the tag as described in the JVM specifications.
+	 * Returns the tag as described in the JVM specifications.
 	 * 
 	 * @return the tag
 	 */
 	int getTag();
 	
 	/**
-	 * Answer back the number of values as described in the JVM specifications.
-	 * This is initialized only if the tag item is '['.
+	 * Returns the number of values as described in the JVM specifications
+	 * if the tag item is '['.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the number of values
 	 */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java
index 481f970..0093a66 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAnnotationDefaultAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java
index e3b6da2..0bdc102 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IAttributeNamesConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java
index 4f35578..a2c23ee 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IBytecodeVisitor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java
index cefeb23..c3b5948 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java
index abfe096..7805f76 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileDisassembler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java
index c83aec5..69acad3 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IClassFileReader.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java
index bdd82fe..94d6a7f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ICodeAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java
index c7f75bf..d536a57 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPool.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java
index 60bcf94..e7bd618 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolConstant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java
index b075e30..ec482c8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantPoolEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,22 +21,24 @@
 public interface IConstantPoolEntry {
 
 	/**
-	 * Answer back the type of this entry.
+	 * Returns the type of this entry.
 	 * 
 	 * @return the type of this entry
 	 */
 	int getKind();
 
 	/**
-	 * Answer back the name index for a CONSTANT_Class type entry.
+	 * Returns the name index for a CONSTANT_Class type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the name index for a CONSTANT_Class type entry
 	 */
 	int getClassInfoNameIndex();
 
 	/**
-	 * Answer back the class index for a CONSTANT_Fieldref,
+	 * Returns the class index for a CONSTANT_Fieldref,
 	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the class index for a CONSTANT_Fieldref,
 	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry
@@ -44,8 +46,9 @@
 	int getClassIndex();
 
 	/**
-	 * Answer back the nameAndType index for a CONSTANT_Fieldref,
+	 * Returns the nameAndType index for a CONSTANT_Fieldref,
 	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the nameAndType index for a CONSTANT_Fieldref,
 	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry
@@ -53,71 +56,81 @@
 	int getNameAndTypeIndex();
 	
 	/**
-	 * Answer back the string index for a CONSTANT_String type entry.
+	 * Returns the string index for a CONSTANT_String type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the string index for a CONSTANT_String type entry
 	 */
 	int getStringIndex();
 
 	/**
-	 * Answer back the string value for a CONSTANT_String type entry.
+	 * Returns the string value for a CONSTANT_String type entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the string value for a CONSTANT_String type entry
 	 */
 	String getStringValue();
 	
 	/**
-	 * Answer back the integer value for a CONSTANT_Integer type entry.
+	 * Returns the integer value for a CONSTANT_Integer type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the integer value for a CONSTANT_Integer type entry
 	 */
 	int getIntegerValue();
 
 	/**
-	 * Answer back the float value for a CONSTANT_Float type entry.
+	 * Returns the float value for a CONSTANT_Float type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the float value for a CONSTANT_Float type entry
 	 */
 	float getFloatValue();
 
 	/**
-	 * Answer back the double value for a CONSTANT_Double type entry.
+	 * Returns the double value for a CONSTANT_Double type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the double value for a CONSTANT_Double type entry
 	 */
 	double getDoubleValue();
 
 	/**
-	 * Answer back the long value for a CONSTANT_Long type entry.
+	 * Returns the long value for a CONSTANT_Long type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the long value for a CONSTANT_Long type entry
 	 */
 	long getLongValue();
 	
 	/**
-	 * Answer back the descriptor index for a CONSTANT_NameAndType type entry.
+	 * Returns the descriptor index for a CONSTANT_NameAndType type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the descriptor index for a CONSTANT_NameAndType type entry
 	 */
 	int getNameAndTypeInfoDescriptorIndex();
 
 	/**
-	 * Answer back the name index for a CONSTANT_NameAndType type entry.
+	 * Returns the name index for a CONSTANT_NameAndType type entry.
+	 * The value is unspecified otherwise.
 	 * 
 	 * @return the name index for a CONSTANT_NameAndType type entry
 	 */
 	int getNameAndTypeInfoNameIndex();
 
 	/**
-	 * Answer back the class name for a CONSTANT_Class type entry.
+	 * Returns the class name for a CONSTANT_Class type entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the class name for a CONSTANT_Class type entry
 	 */
 	char[] getClassInfoName();
 
 	/**
-	 * Answer back the class name for a CONSTANT_Fieldref,
+	 * Returns the class name for a CONSTANT_Fieldref,
 	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the class name for a CONSTANT_Fieldref,
 	 * CONSTANT_Methodref, CONSTANT_InterfaceMethodref type entry
@@ -125,15 +138,17 @@
 	char[] getClassName();
 
 	/**
-	 * Answer back the field name for a CONSTANT_Fieldref type entry.
+	 * Returns the field name for a CONSTANT_Fieldref type entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the field name for a CONSTANT_Fieldref type entry
 	 */
 	char[] getFieldName();
 	
 	/**
-	 * Answer back the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred
+	 * Returns the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred
 	 * type entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the field name for a CONSTANT_Methodref or CONSTANT_InterfaceMethodred
 	 * type entry
@@ -141,8 +156,9 @@
 	char[] getMethodName();
 
 	/**
-	 * Answer back the field descriptor value for a CONSTANT_Fieldref type entry. This value
+	 * Returns the field descriptor value for a CONSTANT_Fieldref type entry. This value
 	 * is set only when decoding the CONSTANT_Fieldref entry. 
+	 * Returns null otherwise.
 	 * 
 	 * @return the field descriptor value for a CONSTANT_Fieldref type entry. This value
 	 * is set only when decoding the CONSTANT_Fieldref entry
@@ -150,9 +166,10 @@
 	char[] getFieldDescriptor();
 
 	/**
-	 * Answer back the method descriptor value for a CONSTANT_Methodref or
+	 * Returns the method descriptor value for a CONSTANT_Methodref or
 	 * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the 
 	 * CONSTANT_Methodref or CONSTANT_InterfaceMethodref entry. 
+	 * Returns null otherwise.
 	 * 
 	 * @return the method descriptor value for a CONSTANT_Methodref or
 	 * CONSTANT_InterfaceMethodref type entry. This value is set only when decoding the 
@@ -161,8 +178,9 @@
 	char[] getMethodDescriptor();
 	
 	/**
-	 * Answer back the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when
+	 * Returns the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when
 	 * decoding a UTF8 entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the utf8 value for a CONSTANT_Utf8 type entry. This value is set only when
 	 * decoding a UTF8 entry
@@ -170,8 +188,9 @@
 	char[] getUtf8Value();
 	
 	/**
-	 * Answer back the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when
+	 * Returns the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when
 	 * decoding a UTF8 entry.
+	 * Returns null otherwise.
 	 * 
 	 * @return the utf8 length for a CONSTANT_Utf8 type entry. This value is set only when
 	 * decoding a UTF8 entry
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java
index 213eef9..4849dcb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IConstantValueAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java
index 7cade9b..0088464 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IEnclosingMethodAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java
index e6f7b43..c3d9c20 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java
index 3fab2a9..decb049 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IExceptionTableEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java
index df0e4ef..ebabb40 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IFieldInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java
index 1fb4298..e89e12e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java
index 6739008..dc90439 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IInnerClassesAttributeEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java
index 6d42786..c91f409 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILineNumberAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java
index 1f863e8..676d8ff 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java
index 17d1b58..8b2fbf0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTableEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java
index 3f87909..fdc0eda 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java
index e1e58cf..4c4a3ba 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ILocalVariableTypeTableEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java
index 9676c43..4fa8072 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IMethodInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java
index 832bbe9..dc59354 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IModifierConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java
index 9af9769..73b0721 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IOpcodeMnemonics.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java
index 1ed9b2c..1016077 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IParameterAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java
index 4ccf75f..6a6fe94 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java
index c02b751..aa5797d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeInvisibleParameterAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java
index 471975c..f70ac57 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java
index b761842..433fd41 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IRuntimeVisibleParameterAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java
index 5322bc4..46c1779 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISignatureAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java
index 48f8d65..2bdd925 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ISourceAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java
index 8f02d82..e78fcbb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/IVerificationTypeInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java
index 4d90aca..b1fa9d1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/OpcodeStringValues.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
index ae47d02..b0e42e9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -94,11 +94,8 @@
 		if (scanner.commentStops[lastCommentIndex] < 0) {
 			continue nextComment;
 		}
-		int commentSourceEnd = scanner.commentStops[lastCommentIndex] - 1; //stop is one over
 		deprecated =
-			this.javadocParser.checkDeprecation(
-				commentSourceStart,
-				commentSourceEnd);
+			this.javadocParser.checkDeprecation(lastCommentIndex);
 		break nextComment;
 	}
 	if (deprecated) {
@@ -489,16 +486,7 @@
 		declaration.type = type;
 	} else {
 		int dimension = typeDim + extendedTypeDimension;
-		//on the identifierLengthStack there is the information about the type....
-		int baseType;
-		if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
-			//it was a baseType
-			declaration.type = TypeReference.baseTypeReference(-baseType, dimension);
-			declaration.type.sourceStart = type.sourceStart;
-			declaration.type.sourceEnd = type.sourceEnd;
-		} else {
-			declaration.type = this.copyDims(type, dimension);
-		}
+		declaration.type = this.copyDims(type, dimension);
 	}
 	variablesCounter[nestedType]++;
 	nestedMethod[nestedType]++;
@@ -586,7 +574,7 @@
 	final int typeDimensions = firstDimensions + extendedDimensions;
 	TypeReference type = getTypeReference(typeDimensions);
 	if (isVarArgs) {
-		type = type.copyDims(typeDimensions + 1);
+		type = copyDims(type, typeDimensions + 1);
 		if (extendedDimensions == 0) {
 			type.sourceEnd = endOfEllipsis;
 		}
@@ -721,6 +709,24 @@
 	typeDecl.javadoc = this.javadoc;
 	this.javadoc = null;
 }
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.compilationUnit.types = new TypeDeclaration[length];
+		this.astPtr -= length;
+		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+	}
+}
 /*
  *
  * INTERNAL USE-ONLY
@@ -842,18 +848,7 @@
 		TypeReference returnType = md.returnType;
 		md.sourceEnd = endPosition;
 		int dims = returnType.dimensions() + extendedDims;
-		int baseType;
-		if ((baseType = identifierLengthStack[identifierLengthPtr + 1]) < 0) {
-			//it was a baseType
-			int sourceStart = returnType.sourceStart;
-			int sourceEnd = returnType.sourceEnd;
-			returnType = TypeReference.baseTypeReference(-baseType, dims);
-			returnType.sourceStart = sourceStart;
-			returnType.sourceEnd = sourceEnd;
-			md.returnType = returnType;
-		} else {
-			md.returnType = this.copyDims(md.returnType, dims);
-		}
+		md.returnType = this.copyDims(returnType, dims);
 		if (currentToken == TokenNameLBRACE) {
 			md.bodyStart = endPosition + 1;
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java
index 1c00926..de28a29 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/IDocumentElementRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java
index 4980020..253a680 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java
@@ -1,11 +1,13 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Common Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors: IBM Corporation - initial API and implementation
- ******************************************************************************/
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.internal.compiler;
 
 import org.eclipse.jdt.core.compiler.IProblem;
@@ -156,4 +158,4 @@
 	void exitMethod(int declarationEnd, int defaultValueStart, int defaultValueEnd);
 	
 	void exitType(int declarationEnd);
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
index 49e6a29..256ce09 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -86,9 +86,11 @@
 }
 
 public SourceElementParser(
-	final ISourceElementRequestor requestor, 
-	IProblemFactory problemFactory,
-	CompilerOptions options) {
+		final ISourceElementRequestor requestor, 
+		IProblemFactory problemFactory,
+		CompilerOptions options,
+		boolean reportLocalDeclarations,
+		boolean optimizeStringLiterals) {
 	// we want to notify all syntax error with the acceptProblem API
 	// To do so, we define the record method of the ProblemReporter
 	super(new ProblemReporter(
@@ -100,23 +102,15 @@
 			requestor.acceptProblem(problem);
 		}
 	},
-	true);
+	optimizeStringLiterals);
 	this.requestor = requestor;
 	typeNames = new char[4][];
 	superTypeNames = new char[4][];
 	nestedTypeIndex = 0;
 	this.options = options;
-}
-
-public SourceElementParser(
-	final ISourceElementRequestor requestor, 
-	IProblemFactory problemFactory,
-	CompilerOptions options,
-	boolean reportLocalDeclarations) {
-		this(requestor, problemFactory, options);
-		if (reportLocalDeclarations) {
-			this.localDeclarationVisitor = new LocalDeclarationVisitor();
-		}
+	if (reportLocalDeclarations) {
+		this.localDeclarationVisitor = new LocalDeclarationVisitor();
+	}
 }
 
 public void checkComment() {
@@ -141,7 +135,7 @@
 			int commentEnd = this.scanner.commentStops[lastComment] - 1; //stop is one over,
 			// do not report problem before last parsed comment while recovering code...
 			this.javadocParser.reportProblems = this.currentElement == null || commentEnd > this.lastJavadocEnd;
-			if (this.javadocParser.checkDeprecation(this.scanner.commentStarts[lastComment], commentEnd)) {
+			if (this.javadocParser.checkDeprecation(lastComment)) {
 				checkAndSetModifiers(AccDeprecated);
 			}
 			this.javadoc = this.javadocParser.docComment;	// null if check javadoc is not activated
@@ -180,6 +174,7 @@
 				JavadocMessageSend messageSend = (JavadocMessageSend) reference;
 				int argCount = messageSend.arguments == null ? 0 : messageSend.arguments.length;
 				this.requestor.acceptMethodReference(messageSend.selector, argCount, messageSend.sourceStart);
+				this.requestor.acceptConstructorReference(messageSend.selector, argCount, messageSend.sourceStart);
 				if (messageSend.receiver != null && !messageSend.receiver.isThis()) {
 					acceptJavadocTypeReference(messageSend.receiver);
 				}
@@ -240,6 +235,38 @@
 		this.requestor.acceptTypeReference(annotation.type.getTypeName(), annotation.sourceStart, annotation.sourceEnd);
 	}
 }
+protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
+	boolean previousFlag = reportReferenceInfo;
+	reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
+	super.consumeClassInstanceCreationExpressionQualifiedWithTypeArguments();
+	reportReferenceInfo = previousFlag;
+	if (reportReferenceInfo){
+		AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr];
+		TypeReference typeRef = alloc.type;
+		requestor.acceptConstructorReference(
+			typeRef instanceof SingleTypeReference 
+				? ((SingleTypeReference) typeRef).token
+				: CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
+			alloc.arguments == null ? 0 : alloc.arguments.length, 
+			alloc.sourceStart);
+	}
+}
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	boolean previousFlag = reportReferenceInfo;
+	reportReferenceInfo = false; // not to see the type reference reported in super call to getTypeReference(...)
+	super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	reportReferenceInfo = previousFlag;
+	if (reportReferenceInfo){
+		AllocationExpression alloc = (AllocationExpression)expressionStack[expressionPtr];
+		TypeReference typeRef = alloc.type;
+		requestor.acceptConstructorReference(
+			typeRef instanceof SingleTypeReference 
+				? ((SingleTypeReference) typeRef).token
+				: CharOperation.concatWith(alloc.type.getParameterizedTypeName(), '.'),
+			alloc.arguments == null ? 0 : alloc.arguments.length, 
+			alloc.sourceStart);
+	}
+}
 protected void consumeConstructorHeaderName() {
 	long selectorSourcePositions = this.identifierPositionStack[this.identifierPtr];
 	int selectorSourceEnd = (int) selectorSourcePositions;
@@ -417,7 +444,12 @@
 		// => accept unknown ref on identifier
 		int length = impt.tokens.length-1;
 		int start = (int) (impt.sourcePositions[length] >>> 32);
-		requestor.acceptUnknownReference(impt.tokens[length], start);
+		char[] last = impt.tokens[length];
+		// accept all possible kind for last name, index users will have to select the right one...
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=86901
+		requestor.acceptFieldReference(last, start);
+		requestor.acceptMethodReference(last, 0,start);
+		requestor.acceptTypeReference(last, start);
 		// accept type name
 		if (length > 0) {
 			char[][] compoundName = new char[length][];
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
index 839d904..b0ba625 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
index f375804..42fe9e2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -27,8 +27,10 @@
 import java.util.HashMap;
 
 import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IImportDeclaration;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.ast.*;
@@ -122,7 +124,8 @@
 
 		if (sourceTypes.length == 0) return this.unit;
 		SourceTypeElementInfo topLevelTypeInfo = (SourceTypeElementInfo) sourceTypes[0];
-		this.cu = (ICompilationUnit) topLevelTypeInfo.getHandle().getCompilationUnit();
+		org.eclipse.jdt.core.ICompilationUnit cuHandle = topLevelTypeInfo.getHandle().getCompilationUnit();
+		this.cu = (ICompilationUnit) cuHandle;
 		this.annotationPositions = ((CompilationUnitElementInfo) ((JavaElement) this.cu).getElementInfo()).annotationPositions;
 
 		if (this.annotationPositions != null && this.annotationPositions.size() > 10) { // experimental value
@@ -135,21 +138,22 @@
 		int end = topLevelTypeInfo.getNameSourceEnd();
 
 		/* convert package and imports */
-		if (topLevelTypeInfo.getPackageName() != null
-			&& topLevelTypeInfo.getPackageName().length > 0)
+		char[] packageName = cuHandle.getParent().getElementName().toCharArray();
+		if (packageName.length > 0)
 			// if its null then it is defined in the default package
 			this.unit.currentPackage =
-				createImportReference(topLevelTypeInfo.getPackageName(), start, end, false, AccDefault);
-		ISourceImport[]  sourceImports = topLevelTypeInfo.getImports();
-		int importCount = sourceImports.length;
+				createImportReference(packageName, start, end, false, AccDefault);
+		IImportDeclaration[] importDeclarations = topLevelTypeInfo.getHandle().getCompilationUnit().getImports();
+		int importCount = importDeclarations.length;
 		this.unit.imports = new ImportReference[importCount];
 		for (int i = 0; i < importCount; i++) {
-			ISourceImport sourceImport = sourceImports[i];
+			ImportDeclaration importDeclaration = (ImportDeclaration) importDeclarations[i];
+			ISourceImport sourceImport = (ISourceImport) importDeclaration.getElementInfo();
 			this.unit.imports[i] = createImportReference(
-				sourceImport.getName(), 
+				importDeclaration.getNameWithoutStar().toCharArray(), 
 				sourceImport.getDeclarationSourceStart(),
 				sourceImport.getDeclarationSourceEnd(),
-				sourceImport.onDemand(),
+				importDeclaration.isOnDemand(),
 				sourceImport.getModifiers());
 		}
 		/* convert type(s) */
@@ -214,7 +218,7 @@
 		int start = fieldInfo.getNameSourceStart();
 		int end = fieldInfo.getNameSourceEnd();
 
-		field.name = fieldInfo.getName();
+		field.name = fieldHandle.getElementName().toCharArray();
 		field.sourceStart = start;
 		field.sourceEnd = end;
 		field.declarationSourceStart = fieldInfo.getDeclarationSourceStart();
@@ -328,7 +332,7 @@
 			
 			method = decl;
 		}
-		method.selector = methodInfo.getSelector();
+		method.selector = methodHandle.getElementName().toCharArray();
 		boolean isVarargs = (modifiers & AccVarargs) != 0;
 		method.modifiers = modifiers & ~AccVarargs;
 		method.sourceStart = start;
@@ -340,13 +344,14 @@
 		method.annotations = convertAnnotations(methodHandle);
 
 		/* convert arguments */
-		char[][] argumentTypeNames = methodInfo.getArgumentTypeNames();
+		String[] argumentTypeSignatures = methodHandle.getParameterTypes();
 		char[][] argumentNames = methodInfo.getArgumentNames();
-		int argumentCount = argumentTypeNames == null ? 0 : argumentTypeNames.length;
+		int argumentCount = argumentTypeSignatures == null ? 0 : argumentTypeSignatures.length;
 		long position = ((long) start << 32) + end;
 		method.arguments = new Argument[argumentCount];
 		for (int i = 0; i < argumentCount; i++) {
-			TypeReference typeReference = createTypeReference(argumentTypeNames[i], start, end);
+			char[] typeName = Signature.toCharArray(argumentTypeSignatures[i].toCharArray());
+			TypeReference typeReference = createTypeReference(typeName, start, end);
 			if (isVarargs && i == argumentCount-1) {
 				typeReference.bits |= ASTNode.IsVarArgs;
 			}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java
index 685f560..6990e7a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ASTHolderCUInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Assert.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Assert.java
index 412438c..627e3a4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Assert.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Assert.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java
index 1238430..9d31c94 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BasicCompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -38,17 +38,6 @@
 	this.contents = contents;
 	this.fileName = fileName.toCharArray();
 	this.packageName = packageName;
-
-	int start = fileName.lastIndexOf("/") + 1; //$NON-NLS-1$
-	if (start == 0 || start < fileName.lastIndexOf("\\")) //$NON-NLS-1$
-		start = fileName.lastIndexOf("\\") + 1; //$NON-NLS-1$
-
-	int end = fileName.lastIndexOf("."); //$NON-NLS-1$
-	if (end == -1)
-		end = fileName.length();
-
-	this.mainTypeName = fileName.substring(start, end).toCharArray();
-	this.encoding = null;
 }
 
 public BasicCompilationUnit(char[] contents, char[][] packageName, String fileName, String encoding) {
@@ -115,6 +104,23 @@
 	return this.fileName;
 }
 public char[] getMainTypeName() {
+	if (this.mainTypeName == null) {
+		int start = CharOperation.lastIndexOf('/', this.fileName) + 1;
+		if (start == 0 || start < CharOperation.lastIndexOf('\\', this.fileName))
+			start = CharOperation.lastIndexOf('\\', this.fileName) + 1;
+		int separator = CharOperation.indexOf('|', this.fileName) + 1;
+		if (separator > start) // case of a .class file in a default package in a jar
+			start = separator;
+	
+		int end = CharOperation.lastIndexOf('$', this.fileName);
+		if (end == -1) {
+			end = CharOperation.lastIndexOf('.', this.fileName);
+			if (end == -1)
+				end = this.fileName.length;
+		}
+	
+		this.mainTypeName = CharOperation.subarray(this.fileName, start, end);
+	}
 	return this.mainTypeName;
 }
 public char[][] getPackageName() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java
index ffe2d20..9d55df6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BatchOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -26,6 +26,11 @@
 		this.runnable = runnable;
 	}
 
+	protected boolean canModifyRoots() {
+		// anything in the workspace runnable can modify the roots
+		return true;
+	}
+	
 	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.internal.core.JavaModelOperation#executeOperation()
 	 */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
index 6ca089f..932a72f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BecomeWorkingCopyOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
index 52ce1c0..a196c93 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryField.java
@@ -1,19 +1,21 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import org.eclipse.jdt.core.Flags;
 import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.internal.compiler.env.IBinaryField;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 
 /**
  * @see IField
@@ -57,6 +59,9 @@
 protected char getHandleMementoDelimiter() {
 	return JavaElement.JEM_FIELD;
 }
+public String getKey(boolean forceOpen) throws JavaModelException {
+	return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, forceOpen);
+}
 /*
  * @see IField
  */
@@ -64,6 +69,22 @@
 	IBinaryField info = (IBinaryField) getElementInfo();
 	return new String(ClassFile.translatedName(info.getTypeName()));
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isEnumConstant()
+ */public boolean isEnumConstant() throws JavaModelException {
+	return Flags.isEnum(getFlags());
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedBinaryField(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
 /*
  * @private Debugging purposes
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java
index e03384e..79e894a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -49,6 +49,18 @@
 	if (openableParentInfo == null) return;
 	openableParentInfo.getBinaryChildren(newElements); // forces the initialization
 }
+public String getKey() {
+	try {
+		return getKey(false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.Binding#computeUniqueKey()
+ */
+public abstract String getKey(boolean forceOpen) throws JavaModelException;
 /*
  * @see ISourceReference
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
index 9d7eac6..915b214 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,6 +19,7 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.SourceElementRequestorAdapter;
 import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -153,6 +154,9 @@
 protected char getHandleMementoDelimiter() {
 	return JavaElement.JEM_METHOD;
 }
+public String getKey(boolean forceOpen) throws JavaModelException {
+	return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, forceOpen);
+}
 /*
  * @see IMethod
  */
@@ -286,7 +290,12 @@
 public boolean isMainMethod() throws JavaModelException {
 	return this.isMainMethod(this);
 }
-
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IMethod#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
 /*
  * @see IMethod#isSimilar(IMethod)
  */
@@ -315,7 +324,11 @@
 	buffer.append(")"); //$NON-NLS-1$
 	return buffer.toString();
 }
-/*
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedBinaryMethod(this.parent, this.name, this.parameterTypes, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}/*
  * @private Debugging purposes
  */
 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
index fc3dc29..416f29f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,9 +21,11 @@
 import org.eclipse.jdt.internal.codeassist.CompletionEngine;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -107,8 +109,10 @@
 	} else {
 		engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
 	}
-	if (NameLookup.VERBOSE)
+	if (NameLookup.VERBOSE) {
 		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
 }
 
 /*
@@ -390,6 +394,9 @@
 public IInitializer[] getInitializers() {
 	return NO_INITIALIZERS;
 }
+public String getKey(boolean forceOpen) throws JavaModelException {
+	return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, forceOpen);
+}
 /*
  * @see IType#getMethod(String name, String[] parameterTypeSignatures)
  */
@@ -433,11 +440,36 @@
  */
 public String getSuperclassTypeSignature() throws JavaModelException {
 	IBinaryType info = (IBinaryType) getElementInfo();
-	char[] superclassName = info.getSuperclassName();
-	if (superclassName == null) {
-		return null;
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature != null) {
+		int signatureLength = genericSignature.length;
+		// skip type parameters
+		int index = 0;
+		if (genericSignature[0] == '<') {
+			int count = 1;
+			while (count > 0 && ++index < signatureLength) {
+				switch (genericSignature[index]) {
+					case '<': 
+						count++;
+						break;
+					case '>':
+						count--;
+						break;
+				}
+			}
+			index++;
+		}
+		int start = index;
+		index = Util.scanClassTypeSignature(genericSignature, start) + 1;
+		char[] superclassSig = CharOperation.subarray(genericSignature, start, index);
+		return new String(ClassFile.translatedName(superclassSig));
+	} else {
+		char[] superclassName = info.getSuperclassName();
+		if (superclassName == null) {
+			return null;
+		}
+		return new String(Signature.createTypeSignature(ClassFile.translatedName(superclassName), true));
 	}
-	return new String(Signature.createTypeSignature(ClassFile.translatedName(superclassName), true));
 }
 
 /*
@@ -475,17 +507,51 @@
  */
 public String[] getSuperInterfaceTypeSignatures() throws JavaModelException {
 	IBinaryType info = (IBinaryType) getElementInfo();
-	char[][] names= info.getInterfaceNames();
-	int length;
-	if (names == null || (length = names.length) == 0) {
-		return NO_STRINGS;
+	char[] genericSignature = info.getGenericSignature();
+	if (genericSignature != null) {
+		ArrayList interfaces = new ArrayList();
+		int signatureLength = genericSignature.length;
+		// skip type parameters
+		int index = 0;
+		if (genericSignature[0] == '<') {
+			int count = 1;
+			while (count > 0 && ++index < signatureLength) {
+				switch (genericSignature[index]) {
+					case '<': 
+						count++;
+						break;
+					case '>':
+						count--;
+						break;
+				}
+			}
+			index++;
+		}
+		// skip superclass
+		index = Util.scanClassTypeSignature(genericSignature, index) + 1;
+		while (index  < signatureLength) {
+			int start = index;
+			index = Util.scanClassTypeSignature(genericSignature, start) + 1;
+			char[] interfaceSig = CharOperation.subarray(genericSignature, start, index);
+			interfaces.add(new String(ClassFile.translatedName(interfaceSig)));
+		}
+		int size = interfaces.size();
+		String[] result = new String[size];
+		interfaces.toArray(result);
+		return result;
+	} else {
+		char[][] names= info.getInterfaceNames();
+		int length;
+		if (names == null || (length = names.length) == 0) {
+			return NO_STRINGS;
+		}
+		names= ClassFile.translatedNames(names);
+		String[] strings= new String[length];
+		for (int i= 0; i < length; i++) {
+			strings[i]= new String(Signature.createTypeSignature(names[i], true));
+		}
+		return strings;
 	}
-	names= ClassFile.translatedNames(names);
-	String[] strings= new String[length];
-	for (int i= 0; i < length; i++) {
-		strings[i]= new String(Signature.createTypeSignature(names[i], true));
-	}
-	return strings;
 }
 
 public ITypeParameter[] getTypeParameters() throws JavaModelException {
@@ -500,22 +566,9 @@
 	return typeParameters;
 }
 
-// Get type parameter names
-// TODO (frederic) see if this method needs to be added to API
-public char[][] getTypeParameterNames() throws JavaModelException {
-	String[] typeParameterSignatures = getTypeParameterSignatures();
-	int length = typeParameterSignatures.length;
-	char[][] names = new char[length][];
-	for (int i = 0; i < length; i++) {
-		names[i] = Signature.getTypeVariable(typeParameterSignatures[i]).toCharArray();
-	}
-	return names;
-}
-
 /**
  * @see IType#getTypeParameterSignatures()
  * @since 3.0
- * @deprecated
  */
 public String[] getTypeParameterSignatures() throws JavaModelException {
 	IBinaryType info = (IBinaryType) getElementInfo();
@@ -600,9 +653,13 @@
  */
 public boolean isInterface() throws JavaModelException {
 	IBinaryType info = (IBinaryType) getElementInfo();
-	return info.getKind() == IGenericType.INTERFACE_DECL;
+	switch (info.getKind()) {
+		case IGenericType.INTERFACE_DECL:
+		case IGenericType.ANNOTATION_TYPE_DECL: // annotation is interface too
+			return true;
+	}
+	return false;
 }
-
 /**
  * @see IType#isAnnotation()
  * @since 3.0
@@ -626,6 +683,12 @@
 	IBinaryType info = (IBinaryType) getElementInfo();
 	return info.isMember();
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IType#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
 /*
  * @see IType
  */
@@ -704,7 +767,7 @@
  */
 public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
 	if (project == null) {
-		throw new IllegalArgumentException(Util.bind("hierarchy.nullProject")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.hierarchy_nullProject); 
 	}
 	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
 	ICompilationUnit[] projectWCs = null;
@@ -785,6 +848,11 @@
 	op.runOperation(monitor);
 	return op.getResult();	
 }
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedBinaryType(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
 /*
  * @see IType#resolveType(String)
  */
@@ -845,7 +913,11 @@
 		toStringName(buffer);
 	} else {
 		try {
-			if (this.isInterface()) {
+			if (this.isAnnotation()) {
+				buffer.append("@interface "); //$NON-NLS-1$
+			} else if (this.isEnum()) {
+				buffer.append("enum "); //$NON-NLS-1$
+			} else if (this.isInterface()) {
 				buffer.append("interface "); //$NON-NLS-1$
 			} else {
 				buffer.append("class "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java
index daa08c1..5182406 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryTypeConverter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -192,7 +192,6 @@
 			}
 		}
 		boolean isInterface = type.isInterface();
-		boolean isAnnotation = type.isAnnotation();
 		neededCount = isInterface ? 0 : neededCount;
 		typeDeclaration.methods = new AbstractMethodDeclaration[methodCount + neededCount];
 		if (neededCount != 0) { // add default constructor in first position
@@ -202,7 +201,7 @@
 		for (int i = 0; i < methodCount; i++) {
 			AbstractMethodDeclaration method =convert(methods[i], type, compilationResult);
 			boolean isAbstract;
-			if ((isAbstract = method.isAbstract()) || isInterface || isAnnotation) { // fix-up flag 
+			if ((isAbstract = method.isAbstract()) || isInterface) { // fix-up flag 
 				method.modifiers |= CompilerModifiers.AccSemicolonBody;
 			}
 			if (isAbstract) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java
index 7f60509..c24fbd0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java
index fc4211d..c5252ab 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java
index 44538e2..ca2f16c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferFactoryWrapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java
index 86afb40..5ade7f2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BufferManager.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
index 377371e..2110dde 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -54,4 +54,4 @@
 		checkCanceled();
 		super.findTypes(prefix, storage);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java
index a67e431..8108478 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableProblemFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -30,4 +30,4 @@
 			throw new AbortCompilation(true/*silent*/, new OperationCanceledException());
 		return super.createProblem(originatingFileName, problemId, problemArguments, messageArguments, severity, startPosition, endPosition, lineNumber);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
index 2fb4280..4ece9fb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,6 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
-import org.eclipse.core.resources.*;
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
@@ -61,7 +60,9 @@
  */
 protected ClassFile(PackageFragment parent, String name) {
 	super(parent);
-	this.name = name;
+	// don't hold on the .class file extension to save memory
+	// also make sure to copy the string (so that it doesn't hold on the underlying char[] that might be much bigger than necessary)
+	this.name = new String(name.substring(0, name.length() - 6)); // don't hold on the .class file extension to save memory
 	this.checkAutomaticSourceMapping = false;
 }
 
@@ -223,7 +224,7 @@
 				if (ze != null) {
 					byte contents[] = org.eclipse.jdt.internal.compiler.util.Util.getZipEntryByteContent(ze, zip);
 					String fileName = root.getHandleIdentifier() + IDependent.JAR_FILE_ENTRY_SEPARATOR + entryName;
-					info = new ClassFileReader(contents, fileName.toCharArray());
+					info = new ClassFileReader(contents, fileName.toCharArray(), true/*fully initialize so as to not keep a reference to the byte array*/);
 				}
 			} finally {
 				JavaModelManager.getJavaModelManager().closeZipFile(zip);
@@ -250,7 +251,7 @@
 	} else {
 		byte[] contents = Util.getResourceContentsAsByteArray(file);
 		try {
-			return new ClassFileReader(contents, file.getFullPath().toString().toCharArray());
+			return new ClassFileReader(contents, file.getFullPath().toString().toCharArray(), true/*fully initialize so as to not keep a reference to the byte array*/);
 		} catch (ClassFormatException cfe) {
 			//the structure remains unknown
 			return null;
@@ -313,11 +314,11 @@
 		return null;
 	} else {		
 		String prefix = null;
-		int index = name.indexOf('$');
+		int index = this.name.indexOf('$');
 		if (index > -1) {
-			prefix = name.substring(0, index);
+			prefix = this.name.substring(0, index);
 		} else {
-			prefix = name.substring(0, name.indexOf('.'));
+			prefix = this.name;
 		}
 		
 		
@@ -361,7 +362,7 @@
 	}
 }
 public String getElementName() {
-	return this.name;
+	return this.name + SuffixConstants.SUFFIX_STRING_class;
 }
 /**
  * @see IJavaElement
@@ -451,18 +452,15 @@
  */
 public IType getType() {
 	if (this.binaryType == null) {
-		// Remove the ".class" from the name of the ClassFile - always works
-		// since constructor fails if name does not end with ".class"
-		String typeName = this.name.substring(0, this.name.lastIndexOf('.'));
-		typeName = typeName.substring(typeName.lastIndexOf('.') + 1);
-		int index = typeName.lastIndexOf('$');
-		if (index > -1) {
-			typeName = Util.localTypeName(typeName, index, typeName.length());
-		}
-		this.binaryType = new BinaryType(this, typeName);
+		this.binaryType = new BinaryType(this, getTypeName());
 	}
 	return this.binaryType;
 }
+public String getTypeName() {
+	// Internal class file name doesn't contain ".class" file extension
+	int lastDollar = this.name.lastIndexOf('$');
+	return lastDollar > -1 ? Util.localTypeName(this.name, lastDollar, this.name.length()) : this.name;
+}
 /*
  * @see IClassFile
  */
@@ -556,14 +554,15 @@
 			try {
 				jar = jarPackageFragmentRoot.getJar();
 				String[] pkgName = ((PackageFragment) getParent()).names;
-				for (int i = 0, length = Util.JAVA_LIKE_EXTENSIONS.length; i < length; i++) {
+				char[][] javaLikeExtensions = Util.getJavaLikeExtensions();
+				for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
 					StringBuffer entryName = new StringBuffer();
 					for (int j = 0, pkgNameLength = pkgName.length; j < pkgNameLength; j++) {
 						entryName.append(pkgName[j]);
 						entryName.append('/');
 					}
 					entryName.append(sourceFileWithoutExtension);
-					entryName.append(Util.JAVA_LIKE_EXTENSIONS[i]);
+					entryName.append(javaLikeExtensions[i]);
 					ZipEntry zipEntry = jar.getEntry(entryName.toString());
 					if (zipEntry != null) {
 						// found a source file
@@ -591,7 +590,7 @@
 			} else	{
 				// root is a class folder
 				
-				IFolder pkgFolder = (IFolder) getParent().getResource();
+				IContainer pkgFolder = (IContainer) getParent().getResource();
 				IResource[] files = null;
 				try {
 					files = pkgFolder.members();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java
index 769511b..65a2d89 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -68,9 +68,10 @@
 	if (fields == null) {
 		return;
 	}
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
 	for (int i = 0, fieldCount = fields.length; i < fieldCount; i++) {
 		IBinaryField fieldInfo = fields[i];
-		IField field = new BinaryField((JavaElement)type, new String(fieldInfo.getName()));
+		IField field = new BinaryField((JavaElement)type, manager.intern(new String(fieldInfo.getName())));
 		newElements.put(field, fieldInfo);
 		childrenHandles.add(field);
 	}
@@ -123,12 +124,14 @@
 			paramNames[j]= pNames[j].toCharArray();
 		}
 		char[][] parameterTypes = ClassFile.translatedNames(paramNames);
+		JavaModelManager manager = JavaModelManager.getJavaModelManager();
 		String selector = new String(methodInfo.getSelector());
 		if (methodInfo.isConstructor()) {
-			selector = type.getElementName();
+			selector =type.getElementName();
 		}
+		selector =  manager.intern(selector);
 		for (int j= 0; j < pNames.length; j++) {
-			pNames[j]= new String(parameterTypes[j]);
+			pNames[j]= manager.intern(new String(parameterTypes[j]));
 		}
 		BinaryMethod method = new BinaryMethod((JavaElement)type, selector, pNames);
 		childrenHandles.add(method);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java
index 8118d00..fbbc2ba 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAccessRule.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAccessRule.java
new file mode 100644
index 0000000..9beb6d1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAccessRule.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
+
+public class ClasspathAccessRule extends AccessRule implements IAccessRule {
+	
+	public ClasspathAccessRule(IPath pattern, int kind) {
+		this(pattern.toString().toCharArray(), toProblemId(kind));
+	}
+	
+	public ClasspathAccessRule(char[] pattern, int problemId) {
+		super(pattern, problemId);
+	}
+	
+	private static int toProblemId(int kind) {
+		switch (kind) {
+			case K_NON_ACCESSIBLE:
+				return IProblem.ForbiddenReference;
+			case K_DISCOURAGED:
+				return IProblem.DiscouragedReference;
+			default:
+				return -1;
+		}
+	}
+
+	public IPath getPattern() {
+		return new Path(new String(this.pattern));
+	}
+
+	public int getKind() {
+		switch (this.problemId) {
+			case IProblem.ForbiddenReference:
+				return K_NON_ACCESSIBLE;
+			case IProblem.DiscouragedReference:
+				return K_DISCOURAGED;
+			default:
+				return K_ACCESSIBLE;
+		}
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAttribute.java
new file mode 100644
index 0000000..9d883b4
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathAttribute.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathAttribute implements IClasspathAttribute {
+	
+	private String name;
+	private String value;
+	
+	public ClasspathAttribute(String name, String value) {
+		this.name = name;
+		this.value = value;
+	}
+	
+	public boolean equals(Object obj) {
+		if (!(obj instanceof ClasspathAttribute)) return false;
+		ClasspathAttribute other = (ClasspathAttribute) obj;
+		return this.name.equals(other.name) && this.value.equals(other.value);
+	}
+
+    public String getName() {
+		return this.name;
+    }
+
+    public String getValue() {
+		return this.value;
+    }
+    
+    public int hashCode() {
+     	return Util.combineHashCodes(this.name.hashCode(), this.value.hashCode());
+    }
+    
+    public String toString() {
+    	return this.name + "=" + this.value; //$NON-NLS-1$
+    }
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
index 548cc0d..5f38317 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -22,6 +22,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
 import org.eclipse.jdt.core.IClasspathContainer;
 import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.IJavaModelStatus;
@@ -31,10 +33,15 @@
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 /**
  * @see IClasspathEntry
@@ -51,6 +58,17 @@
 	public static final String TAG_EXPORTED = "exported"; //$NON-NLS-1$
 	public static final String TAG_INCLUDING = "including"; //$NON-NLS-1$
 	public static final String TAG_EXCLUDING = "excluding"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTES = "attributes"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTE = "attribute"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
+	public static final String TAG_ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$
+	public static final String TAG_COMBINE_ACCESS_RULES = "combineaccessrules"; //$NON-NLS-1$
+	public static final String TAG_ACCESS_RULES = "accessrules"; //$NON-NLS-1$
+	public static final String TAG_ACCESS_RULE = "accessrule"; //$NON-NLS-1$
+	public static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
+	public static final String TAG_ACCESSIBLE = "accessible"; //$NON-NLS-1$
+	public static final String TAG_NON_ACCESSIBLE = "nonaccessible"; //$NON-NLS-1$
+	public static final String TAG_DISCOURAGED = "discouraged"; //$NON-NLS-1$
 	
 	/**
 	 * Describes the kind of classpath entry - one of 
@@ -96,9 +114,10 @@
 	private char[][] fullExclusionPatternChars;
 	private final static char[][] UNINIT_PATTERNS = new char[][] { "Non-initialized yet".toCharArray() }; //$NON-NLS-1$
 	
+	private boolean combineAccessRules;
+	
 	private String rootID;
-	private AccessRestriction importRestriction;
-	private final static AccessRestriction UNINIT_RESTRICTION = new AccessRestriction(null, null, null, null);
+	private AccessRuleSet accessRuleSet;
 	
 	/*
 	 * Default inclusion pattern set
@@ -109,6 +128,16 @@
 	 * Default exclusion pattern set
 	 */
 	public final static IPath[] EXCLUDE_NONE = {};
+	
+	/*
+	 * Default extra attributes
+	 */
+	public final static IClasspathAttribute[] NO_EXTRA_ATTRIBUTES = {};
+	
+	/*
+	 * Default access rules
+	 */
+	public final static IAccessRule[] NO_ACCESS_RULES = {};
 				
 	/**
 	 * Describes the path to the source archive associated with this
@@ -146,6 +175,11 @@
 	 * The export flag
 	 */
 	public boolean isExported;
+	
+	/*
+	 * The extra attributes
+	 */
+	private IClasspathAttribute[] extraAttributes;
 
 	/**
 	 * Creates a class path entry of the specified kind with the given path.
@@ -159,7 +193,10 @@
 		IPath sourceAttachmentPath,
 		IPath sourceAttachmentRootPath,
 		IPath specificOutputLocation,
-		boolean isExported) {
+		boolean isExported,
+		IAccessRule[] accessRules,
+		boolean combineAccessRules,
+		IClasspathAttribute[] extraAttributes) {
 
 		this.contentKind = contentKind;
 		this.entryKind = entryKind;
@@ -167,13 +204,21 @@
 		this.inclusionPatterns = inclusionPatterns;
 		this.exclusionPatterns = exclusionPatterns;
 		
+		AccessRuleSet ruleSet = createAccessRuleSet(accessRules);
+		if (ruleSet != null) {
+			// compute message template
+			ruleSet.messageTemplate = getMessageTemplate();
+		}
+		this.accessRuleSet = ruleSet;
+		
+		this.combineAccessRules = combineAccessRules;
+		this.extraAttributes = extraAttributes;
+		
 	    if (inclusionPatterns != INCLUDE_ALL && inclusionPatterns.length > 0) {
 			this.fullInclusionPatternChars = UNINIT_PATTERNS;
-			this.importRestriction = UNINIT_RESTRICTION;
 	    }
 	    if (exclusionPatterns.length > 0) {
 			this.fullExclusionPatternChars = UNINIT_PATTERNS;
-			this.importRestriction = UNINIT_RESTRICTION;
 	    }
 		this.sourceAttachmentPath = sourceAttachmentPath;
 		this.sourceAttachmentRootPath = sourceAttachmentRootPath;
@@ -181,36 +226,107 @@
 		this.isExported = isExported;
 	}
 	
+	private static AccessRuleSet createAccessRuleSet(IAccessRule[] accessRules) {
+		int length = accessRules == null ? 0 : accessRules.length;
+		if (length == 0) return null;
+		AccessRule[] rules = new AccessRule[length];
+		System.arraycopy(accessRules, 0, rules, 0, length);
+		return new AccessRuleSet(rules);
+	}
+	
+	public boolean combineAccessRules() {
+		return this.combineAccessRules;
+	}
+	
 	/**
 	 * Used to perform export/restriction propagation across referring projects/containers
 	 */
-	public ClasspathEntry combineWith(IClasspathEntry referringEntry) {
+	public ClasspathEntry combineWith(ClasspathEntry referringEntry) {
 		if (referringEntry == null) return this;
-		if (referringEntry.isExported() 
-				|| referringEntry.getInclusionPatterns().length > 0 
-				|| referringEntry.getExclusionPatterns().length > 0) {
+		if (referringEntry.isExported() || referringEntry.getAccessRuleSet() != null ) {
+			boolean combine = this.entryKind == CPE_SOURCE || referringEntry.combineAccessRules();
 			return new ClasspathEntry(
 								this.getContentKind(), this.getEntryKind(), this.getPath(),
-								ClasspathEntry.concatPatterns(referringEntry.getInclusionPatterns(), this.getInclusionPatterns()), 
-								ClasspathEntry.concatPatterns(referringEntry.getExclusionPatterns(), this.getExclusionPatterns()), 
+								this.inclusionPatterns, 
+								this.exclusionPatterns, 
 								this.getSourceAttachmentPath(), this.getSourceAttachmentRootPath(), this.getOutputLocation(), 
-								referringEntry.isExported()|| this.isExported); // duplicate container entry for tagging it as exported
+								referringEntry.isExported() || this.isExported, // duplicate container entry for tagging it as exported
+								combine(referringEntry.getAccessRules(), getAccessRules(), combine),
+								this.combineAccessRules,
+								this.extraAttributes); 
 		}
 		// no need to clone
 		return this;
 	}
 
-	/**
-	 * Concatenate two pattern lists
-	 */
-	public static IPath[] concatPatterns(IPath[] patternList1, IPath[] patternList2) {
-		int length1 = patternList1.length;
-		if (length1 == 0) return patternList2;
-		int length2 = patternList2.length;
-		if (length2 == 0) return patternList1;
-		IPath[] result = new IPath[length1+length2];
-		System.arraycopy(patternList1, 0, result, 0, length1);
-		System.arraycopy(patternList2, 0, result, length1, length2);
+	private IAccessRule[] combine(IAccessRule[] referringRules, IAccessRule[] rules, boolean combine) {
+		if (!combine) return rules;
+		if (rules == null) return referringRules;
+		
+		// concat access rules
+		int referringRulesLength = referringRules.length;
+		int accessRulesLength = rules.length;
+		int rulesLength = referringRulesLength + accessRulesLength;
+		IAccessRule[] result = new IAccessRule[rulesLength];
+		System.arraycopy(referringRules, 0, result, 0, referringRulesLength);
+		System.arraycopy(rules, 0, result, referringRulesLength, accessRulesLength);
+		
+		return result;
+	}
+
+	private static IClasspathAttribute[] decodeExtraAttributes(Element element) {
+		Node extra = element.getElementsByTagName(TAG_ATTRIBUTES).item(0);
+		if (extra == null) return NO_EXTRA_ATTRIBUTES;
+		NodeList attributes = element.getElementsByTagName(TAG_ATTRIBUTE);
+		if (attributes == null) return NO_EXTRA_ATTRIBUTES;
+		int length = attributes.getLength();
+		if (length == 0) return NO_EXTRA_ATTRIBUTES;
+		IClasspathAttribute[] result = new IClasspathAttribute[length];
+		int index = 0;
+		for (int i = 0; i < length; ++i) {
+			Node node = attributes.item(i);
+			if (node.getNodeType() == Node.ELEMENT_NODE) {
+				Element attribute = (Element)node;
+				String name = attribute.getAttribute(TAG_ATTRIBUTE_NAME);
+				if (name == null) continue;
+				String value = attribute.getAttribute(TAG_ATTRIBUTE_VALUE);
+				if (value == null) continue;
+				result[index++] = new ClasspathAttribute(name, value);
+			}
+		}
+		if (index != length)
+			System.arraycopy(result, 0, result = new IClasspathAttribute[index], 0, index);
+		return result;
+	}
+	
+	private static IAccessRule[] decodeAccessRules(Element element) {
+		Node accessRules = element.getElementsByTagName(TAG_ACCESS_RULES).item(0);
+		if (accessRules == null || accessRules.getNodeType() != Node.ELEMENT_NODE) return null;
+		NodeList list = ((Element) accessRules).getElementsByTagName(TAG_ACCESS_RULE);
+		int length = list.getLength();
+		if (length == 0) return null;
+		IAccessRule[] result = new IAccessRule[length];
+		int index = 0;
+		for (int i = 0; i < length; i++) {
+			Node accessRule = list.item(i);
+			if (accessRule == null || accessRule.getNodeType() != Node.ELEMENT_NODE) return null;
+			Element elementAccessRule = (Element) accessRule;
+			String pattern = elementAccessRule.getAttribute(TAG_PATTERN);
+			if (pattern == null) continue;
+			String tagKind =  elementAccessRule.getAttribute(TAG_KIND);
+			int kind;
+			if (TAG_ACCESSIBLE.equals(tagKind))
+				kind = IAccessRule.K_ACCESSIBLE;
+			else if (TAG_NON_ACCESSIBLE.equals(tagKind))
+				kind = IAccessRule.K_NON_ACCESSIBLE;
+			else if (TAG_DISCOURAGED.equals(tagKind))
+				kind = IAccessRule.K_DISCOURAGED;
+			else
+				continue;
+			result[index++] = new ClasspathAccessRule(new Path(pattern), kind);
+		}
+		if (index != length)
+			System.arraycopy(result, 0, result = new IAccessRule[index], 0, index);
 		return result;
 	}
 	
@@ -309,6 +425,9 @@
 		}
 		encodePatterns(this.inclusionPatterns, TAG_INCLUDING, parameters);
 		encodePatterns(this.exclusionPatterns, TAG_EXCLUDING, parameters);
+		if (this.entryKind == CPE_PROJECT && !this.combineAccessRules)
+			parameters.put(TAG_COMBINE_ACCESS_RULES, "false"); //$NON-NLS-1$
+		
 		
 		if (this.specificOutputLocation != null) {
 			IPath outputLocation = this.specificOutputLocation.removeFirstSegments(1);
@@ -316,7 +435,61 @@
 			parameters.put(TAG_OUTPUT, String.valueOf(outputLocation));
 		}
 
-		writer.printTag(TAG_CLASSPATHENTRY, parameters, indent, newLine, true);
+		boolean hasExtraAttributes = this.extraAttributes != NO_EXTRA_ATTRIBUTES;
+		boolean hasRestrictions = getAccessRuleSet() != null;
+		writer.printTag(TAG_CLASSPATHENTRY, parameters, indent, newLine, !hasExtraAttributes && !hasRestrictions /*close tag if no extra attributes and no restriction*/);
+		
+		if (hasExtraAttributes)
+			encodeExtraAttributes(writer, indent, newLine);
+	
+		if (hasRestrictions)
+			encodeAccessRules(writer, indent, newLine);
+
+		if (hasExtraAttributes || hasRestrictions)
+			writer.endTag(TAG_CLASSPATHENTRY, indent);
+	}
+	
+	private void encodeExtraAttributes(XMLWriter writer, boolean indent, boolean newLine) {
+		writer.startTag(TAG_ATTRIBUTES, indent);
+		for (int i = 0; i < this.extraAttributes.length; i++) {
+			IClasspathAttribute attribute = this.extraAttributes[i];
+			HashMap parameters = new HashMap();
+	    	parameters.put(TAG_ATTRIBUTE_NAME, attribute.getName());
+			parameters.put(TAG_ATTRIBUTE_VALUE, attribute.getValue());
+			writer.printTag(TAG_ATTRIBUTE, parameters, indent, newLine, true);
+		}
+		writer.endTag(TAG_ATTRIBUTES, indent);
+	}
+	
+	private void encodeAccessRules(XMLWriter writer, boolean indent, boolean newLine) {
+
+		writer.startTag(TAG_ACCESS_RULES, indent);
+		AccessRule[] rules = getAccessRuleSet().getAccessRules();
+		for (int i = 0, length = rules.length; i < length; i++) {
+			encodeAccessRule(rules[i], writer, indent, newLine);
+		}
+		writer.endTag(TAG_ACCESS_RULES, indent);
+	}
+	
+	private void encodeAccessRule(AccessRule accessRule, XMLWriter writer, boolean indent, boolean newLine) {
+
+		HashMap parameters = new HashMap();
+		parameters.put(TAG_PATTERN, new String(accessRule.pattern));
+		
+		switch (accessRule.problemId) {
+			case IProblem.ForbiddenReference:
+				parameters.put(TAG_KIND, TAG_NON_ACCESSIBLE);
+				break;
+			case IProblem.DiscouragedReference:
+				parameters.put(TAG_KIND, TAG_DISCOURAGED);
+				break;
+			default:
+				parameters.put(TAG_KIND, TAG_ACCESSIBLE);
+				break;
+		}
+		
+		writer.printTag(TAG_ACCESS_RULE, parameters, indent, newLine, true);
+
 	}
 	
 	public static IClasspathEntry elementDecode(Element element, IJavaProject project) {
@@ -355,63 +528,80 @@
 		IPath[] exclusionPatterns = decodePatterns(element, TAG_EXCLUDING);
 		if (exclusionPatterns == null) exclusionPatterns = EXCLUDE_NONE;
 		
+		// access rules (optional)
+		IAccessRule[] accessRules = decodeAccessRules(element);
+		
+		// backward compatibility
+		if (accessRules == null) {
+			accessRules = getAccessRules(inclusionPatterns, exclusionPatterns);
+		}
+
+		// combine access rules (optional)
+		boolean combineAccessRestrictions = !element.getAttribute(TAG_COMBINE_ACCESS_RULES).equals("false"); //$NON-NLS-1$
+		
+		// extra attributes (optional)
+		IClasspathAttribute[] extraAttributes = decodeExtraAttributes(element);
+		
 		// custom output location
 		IPath outputLocation = element.hasAttribute(TAG_OUTPUT) ? projectPath.append(element.getAttribute(TAG_OUTPUT)) : null;
 		
 		// recreate the CP entry
+		IClasspathEntry entry = null;
 		switch (kind) {
 
 			case IClasspathEntry.CPE_PROJECT :
-				return JavaCore.newProjectEntry(
+				entry = JavaCore.newProjectEntry(
 												path, 
-												inclusionPatterns,
-												exclusionPatterns,
+												accessRules,
+												combineAccessRestrictions,
+												extraAttributes,
 												isExported);
-				
+				break;				
 			case IClasspathEntry.CPE_LIBRARY :
-				return JavaCore.newLibraryEntry(
+				entry = JavaCore.newLibraryEntry(
 												path,
 												sourceAttachmentPath,
 												sourceAttachmentRootPath,
-												inclusionPatterns,
-												exclusionPatterns,
+												accessRules,
+												extraAttributes,
 												isExported);
-				
+				break;
 			case IClasspathEntry.CPE_SOURCE :
 				// must be an entry in this project or specify another project
 				String projSegment = path.segment(0);
 				if (projSegment != null && projSegment.equals(project.getElementName())) { // this project
-					return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation);
+					return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation, extraAttributes);
 				} else { 
 					if (path.segmentCount() == 1) {
 						// another project
-						return JavaCore.newProjectEntry(
+						entry = JavaCore.newProjectEntry(
 												path, 
-												inclusionPatterns,
-												exclusionPatterns,
+												accessRules,
+												combineAccessRestrictions,
+												extraAttributes,
 												isExported);
 					} else {
 						// an invalid source folder
-						return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation);
+						return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation, extraAttributes);
 					}
 				}
-
+				break;
 			case IClasspathEntry.CPE_VARIABLE :
-				return JavaCore.newVariableEntry(
+				entry = JavaCore.newVariableEntry(
 						path,
 						sourceAttachmentPath,
 						sourceAttachmentRootPath, 
-						inclusionPatterns,
-						exclusionPatterns,
+						accessRules,
+						extraAttributes,
 						isExported);
-				
+				break;
 			case IClasspathEntry.CPE_CONTAINER :
-				return JavaCore.newContainerEntry(
+				entry = JavaCore.newContainerEntry(
 						path,
-						inclusionPatterns,
-						exclusionPatterns,
+						accessRules,
+						extraAttributes,
 						isExported);
-
+				break;
 			case ClasspathEntry.K_OUTPUT :
 				if (!path.isAbsolute()) return null;
 				return new ClasspathEntry(
@@ -423,10 +613,14 @@
 						null, // source attachment
 						null, // source attachment root
 						null, // custom output location
-						false);
+						false,
+						null,
+						false, // no accessible files to combine
+						NO_EXTRA_ATTRIBUTES);
 			default :
-				throw new Assert.AssertionFailedException(Util.bind("classpath.unknownKind", kindAttr)); //$NON-NLS-1$
+				throw new Assert.AssertionFailedException(Messages.bind(Messages.classpath_unknownKind, kindAttr)); 
 		}
+		return entry;
 	}
 
 	/**
@@ -450,8 +644,8 @@
 	public boolean equals(Object object) {
 		if (this == object)
 			return true;
-		if (object instanceof IClasspathEntry) {
-			IClasspathEntry otherEntry = (IClasspathEntry) object;
+		if (object instanceof ClasspathEntry) {
+			ClasspathEntry otherEntry = (ClasspathEntry) object;
 
 			if (this.contentKind != otherEntry.getContentKind())
 				return false;
@@ -487,6 +681,14 @@
 				return false;
 			if (!equalPatterns(this.exclusionPatterns, otherEntry.getExclusionPatterns()))
 				return false;
+			AccessRuleSet otherRuleSet = otherEntry.getAccessRuleSet();
+			if (getAccessRuleSet() != null) {
+				if (!getAccessRuleSet().equals(otherRuleSet))
+					return false;
+			} else if (otherRuleSet != null)
+				return false;
+			if (this.combineAccessRules != otherEntry.combineAccessRules())
+				return false;
 			otherPath = otherEntry.getOutputLocation();
 			if (this.specificOutputLocation == null) {
 				if (otherPath != null)
@@ -495,12 +697,28 @@
 				if (!this.specificOutputLocation.equals(otherPath))
 					return false;
 			}
+			if (!equalAttributes(this.extraAttributes, otherEntry.getExtraAttributes()))
+				return false;
 			return true;
 		} else {
 			return false;
 		}
 	}
 
+	private static boolean equalAttributes(IClasspathAttribute[] firstAttributes, IClasspathAttribute[] secondAttributes) {
+		if (firstAttributes != secondAttributes){
+		    if (firstAttributes == null) return false;
+			int length = firstAttributes.length;
+			if (secondAttributes == null || secondAttributes.length != length) 
+				return false;
+			for (int i = 0; i < length; i++) {
+				if (!firstAttributes[i].equals(secondAttributes[i]))
+					return false;
+			}
+		}
+		return true;
+	}
+	
 	private static boolean equalPatterns(IPath[] firstPatterns, IPath[] secondPatterns) {
 		if (firstPatterns != secondPatterns){
 		    if (firstPatterns == null) return false;
@@ -518,6 +736,23 @@
 	}
 	
 	/**
+	 * @see IClasspathEntry#getAccessRules()
+	 */
+	public IAccessRule[] getAccessRules() {
+		if (this.accessRuleSet == null) return NO_ACCESS_RULES;
+		AccessRule[] rules = this.accessRuleSet.getAccessRules();
+		int length = rules.length;
+		if (length == 0) return NO_ACCESS_RULES;
+		IAccessRule[] result = new IAccessRule[length];
+		System.arraycopy(rules, 0, result, 0, length);
+		return result;
+	}
+	
+	public AccessRuleSet getAccessRuleSet() {
+		return this.accessRuleSet;
+	}
+
+	/**
 	 * @see IClasspathEntry
 	 */
 	public int getContentKind() {
@@ -537,6 +772,29 @@
 	public IPath[] getExclusionPatterns() {
 		return this.exclusionPatterns;
 	}
+	
+	public IClasspathAttribute[] getExtraAttributes() {
+		return this.extraAttributes;
+	}
+	
+	private String getMessageTemplate() {
+		if (this.entryKind == CPE_PROJECT || this.entryKind == CPE_SOURCE) { // can be remote source entry when reconciling
+			return Messages.bind(
+				org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_project,
+				new String[] {"{0}", getPath().segment(0)});  //$NON-NLS-1$
+		} else {
+			IPath libPath = getPath();
+			Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), libPath, false);
+			String pathString;
+			if (target instanceof java.io.File)
+				pathString = libPath.toOSString();
+			else
+				pathString = libPath.makeRelative().toString();
+			return Messages.bind(
+				org.eclipse.jdt.internal.core.util.Messages.restrictedAccess_library,
+				new String[] {"{0}", pathString}); //$NON-NLS-1$ 
+		}
+	}
 
 	/**
 	 * @see IClasspathEntry#getExclusionPatterns()
@@ -546,40 +804,6 @@
 	}
 
 	/**
-	 * Defines access restriction rules for project import
-	 */	
-	public AccessRestriction getImportRestriction() {
-		
-		if (this.importRestriction == UNINIT_RESTRICTION) {
-			char[][] importIncludes = getAccessRestrictionPatterns(this.inclusionPatterns);
-			char[][] importExcludes = getAccessRestrictionPatterns(this.exclusionPatterns);
-			if (importIncludes == null && importExcludes == null) {
-				this.importRestriction = null;
-			} else {
-				this.importRestriction = new AccessRestriction(
-									(this.entryKind == CPE_PROJECT || this.entryKind == CPE_SOURCE) // can be remote source entry when reconciling
-										? org.eclipse.jdt.internal.core.util.Util.bind("restrictedAccess.project", null, getPath().segment(0)) //$NON-NLS-1$
-										: org.eclipse.jdt.internal.core.util.Util.bind("restrictedAccess.library", null, getPath().makeRelative().toOSString()), //$NON-NLS-1$
-									importIncludes, 
-									importExcludes,
-									null /* no further restriction */);
-			}
-		}
-		return this.importRestriction;
-	}
-	
-	public static char[][] getAccessRestrictionPatterns(IPath[] patternSequence) {
-		if (patternSequence == null) return null;
-		int length = patternSequence.length;
-		if (length == 0) return null;
-		char[][] patternChars = new char[length][];
-		for (int i = 0; i < length; i++) {
-			patternChars[i] = patternSequence[i].toString().toCharArray();
-		}
-		return patternChars;
-	}		
-
-	/**
 	 * @see IClasspathEntry#getOutputLocation()
 	 */
 	public IPath getOutputLocation() {
@@ -592,7 +816,7 @@
 	public IPath getPath() {
 		return this.path;
 	}
-
+	
 	/**
 	 * @see IClasspathEntry
 	 */
@@ -664,6 +888,21 @@
 		}
 	}
 
+	public static IAccessRule[] getAccessRules(IPath[] accessibleFiles, IPath[] nonAccessibleFiles) {
+		int accessibleFilesLength = accessibleFiles == null ? 0 : accessibleFiles.length;
+		int nonAccessibleFilesLength = nonAccessibleFiles == null ? 0 : nonAccessibleFiles.length;
+		int length = accessibleFilesLength + nonAccessibleFilesLength;
+		if (length == 0) return null;
+		IAccessRule[] accessRules = new IAccessRule[length];
+		for (int i = 0; i < accessibleFilesLength; i++) {
+			accessRules[i] = JavaCore.newAccessRule(accessibleFiles[i], IAccessRule.K_ACCESSIBLE);
+		}
+		for (int i = 0; i < nonAccessibleFilesLength; i++) {
+			accessRules[accessibleFilesLength + i] = JavaCore.newAccessRule(nonAccessibleFiles[i], IAccessRule.K_NON_ACCESSIBLE);
+		}
+		return accessRules;
+	}
+	
 	/**
 	 * Returns a printable representation of this classpath entry.
 	 */
@@ -714,7 +953,7 @@
 		buffer.append("[isExported:"); //$NON-NLS-1$
 		buffer.append(this.isExported);
 		buffer.append(']');
-		IPath[] patterns = getInclusionPatterns();
+		IPath[] patterns = this.inclusionPatterns;
 		int length;
 		if ((length = patterns == null ? 0 : patterns.length) > 0) {
 			buffer.append("[including:"); //$NON-NLS-1$
@@ -726,7 +965,7 @@
 			}
 			buffer.append(']');
 		}
-		patterns = getExclusionPatterns();
+		patterns = this.exclusionPatterns;
 		if ((length = patterns == null ? 0 : patterns.length) > 0) {
 			buffer.append("[excluding:"); //$NON-NLS-1$
 			for (int i = 0; i < length; i++) {
@@ -737,11 +976,31 @@
 			}
 			buffer.append(']');
 		}
+		if (this.accessRuleSet != null) {
+			buffer.append('[');
+			buffer.append(this.accessRuleSet.toString(false/*on one line*/));
+			buffer.append(']');
+		}
+		if (this.entryKind == CPE_PROJECT) {
+			buffer.append("[combine access rules:"); //$NON-NLS-1$
+			buffer.append(this.combineAccessRules);
+			buffer.append(']');
+		}
 		if (getOutputLocation() != null) {
 			buffer.append("[output:"); //$NON-NLS-1$
 			buffer.append(getOutputLocation());
 			buffer.append(']');
 		}
+		if ((length = this.extraAttributes == null ? 0 : this.extraAttributes.length) > 0) {
+			buffer.append("[attributes:"); //$NON-NLS-1$
+			for (int i = 0; i < length; i++) {
+				buffer.append(this.extraAttributes[i]);
+				if (i != length-1) {
+					buffer.append(',');
+				}
+			}
+			buffer.append(']');
+		}
 		return buffer.toString();
 	}
 	
@@ -908,7 +1167,7 @@
 					// output before complaining
 					if (potentialNestedOutput == null) potentialNestedOutput = customOutput;
 				} else {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotNestOutputInOutput", customOutput.makeRelative().toString(), outputLocations[index].makeRelative().toString())); //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInOutput, new String[] {customOutput.makeRelative().toString(), outputLocations[index].makeRelative().toString()})); 
 				}
 			}
 		}	
@@ -916,7 +1175,7 @@
 		if (sourceEntryCount <= outputCount-1) {
 		    allowNestingInOutputLocations[0] = true;
 		} else if (potentialNestedOutput != null) {
-			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotNestOutputInOutput", potentialNestedOutput.makeRelative().toString(), outputLocations[0].makeRelative().toString())); //$NON-NLS-1$
+			return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInOutput, new String[] {potentialNestedOutput.makeRelative().toString(), outputLocations[0].makeRelative().toString()})); 
 		}
 
 		for (int i = 0 ; i < length; i++) {
@@ -959,13 +1218,13 @@
 	
 			// complain if duplicate path
 			if (!pathes.add(entryPath)){
-				return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Util.bind("classpath.duplicateEntryPath", entryPathMsg, projectName)); //$NON-NLS-1$
+				return new JavaModelStatus(IJavaModelStatusConstants.NAME_COLLISION, Messages.bind(Messages.classpath_duplicateEntryPath, new String[] {entryPathMsg, projectName})); 
 			}
 			// no further check if entry coincidates with project or output location
 			if (entryPath.equals(projectPath)){
 				// complain if self-referring project entry
 				if (kind == IClasspathEntry.CPE_PROJECT){
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, Util.bind("classpath.cannotReferToItself", entryPath.makeRelative().toString()));//$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, Messages.bind(Messages.classpath_cannotReferToItself, new String[] {entryPath.makeRelative().toString()}));
 				}
 				// tolerate nesting output in src if src==prj
 				continue;
@@ -989,13 +1248,13 @@
 								&& !Util.isExcluded(entryPath.append("*"), inclusionPatterns = ((ClasspathEntry)otherEntry).fullInclusionPatternChars(), exclusionPatterns = ((ClasspathEntry)otherEntry).fullExclusionPatternChars(), false)) { //$NON-NLS-1$
 							String exclusionPattern = entryPath.removeFirstSegments(otherPath.segmentCount()).segment(0);
 							if (Util.isExcluded(entryPath, inclusionPatterns, exclusionPatterns, false)) {
-								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.mustEndWithSlash", exclusionPattern, entryPath.makeRelative().toString())); //$NON-NLS-1$
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_mustEndWithSlash, new String[] {exclusionPattern, entryPath.makeRelative().toString()})); 
 							} else {
 								if (otherKind == IClasspathEntry.CPE_SOURCE) {
 									exclusionPattern += '/';
-									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotNestEntryInEntry", new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString(), exclusionPattern})); //$NON-NLS-1$
+									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInEntry, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString(), exclusionPattern})); 
 								} else {
-									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotNestEntryInLibrary", entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString())); //$NON-NLS-1$
+									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInLibrary, new String[] {entryPath.makeRelative().toString(), otherEntry.getPath().makeRelative().toString()})); 
 								}
 							}
 						}
@@ -1011,7 +1270,7 @@
     			if (entryPath.equals(currentOutput)) continue;
 				if (entryPath.isPrefixOf(currentOutput)) {
 				    if (kind != IClasspathEntry.CPE_SOURCE || !Util.isExcluded(currentOutput, inclusionPatterns, exclusionPatterns, true)) {
-						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotNestOutputInEntry", currentOutput.makeRelative().toString(), entryPath.makeRelative().toString())); //$NON-NLS-1$
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestOutputInEntry, new String[] {currentOutput.makeRelative().toString(), entryPath.makeRelative().toString()})); 
 				    }
 				}
 		    }
@@ -1021,7 +1280,7 @@
 		        if (allowNestingInOutputLocations[j]) continue;
 		        IPath currentOutput = outputLocations[j];
 				if (currentOutput.isPrefixOf(entryPath)) {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotNestEntryInOutput", entryPath.makeRelative().toString(), currentOutput.makeRelative().toString())); //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotNestEntryInOutput, new String[] {entryPath.makeRelative().toString(), currentOutput.makeRelative().toString()})); 
 				}
 		    }			
 		}
@@ -1055,12 +1314,12 @@
 					switch (otherEntry.getEntryKind()) {
 						case IClasspathEntry.CPE_SOURCE :
 							if (otherEntry.getPath().equals(output)) {
-								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotUseDistinctSourceFolderAsOutput", new String[] {entryPathMsg, otherPathMsg, projectName})); //$NON-NLS-1$
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseDistinctSourceFolderAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); 
 							}
 							break;
 						case IClasspathEntry.CPE_LIBRARY :
 							if (otherEntry.getPath().equals(output)) {
-								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.cannotUseLibraryAsOutput", new String[] {entryPathMsg, otherPathMsg, projectName})); //$NON-NLS-1$
+								return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_cannotUseLibraryAsOutput, new String[] {entryPathMsg, otherPathMsg, projectName})); 
 							}
 					}
 				}
@@ -1129,7 +1388,7 @@
 						return new JavaModelStatus(e);
 					}
 				} else {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalContainerPath", entryPathMsg, projectName));					 //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalContainerPath, new String[] {entryPathMsg, projectName}));					 
 				}
 				break;
 				
@@ -1148,7 +1407,7 @@
 					}
 					return validateClasspathEntry(project, entry, checkSourceAttachment, recurseInContainers);
 				} else {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalVariablePath", entryPathMsg, projectName));					 //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalVariablePath, new String[] {entryPathMsg, projectName}));					 
 				}
 	
 			// library entry check
@@ -1172,10 +1431,10 @@
 										&& sourceAttachment != null
 										&& !sourceAttachment.isEmpty()
 										&& JavaModel.getTarget(workspaceRoot, sourceAttachment, true) == null){
-										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.toString(), projectName})); //$NON-NLS-1$
+										return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), projectName})); 
 									}
 								} else {
-									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalLibraryArchive", entryPathMsg, projectName)); //$NON-NLS-1$
+									return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryArchive, new String[] {entryPathMsg, projectName})); 
 								}
 								break;
 							case IResource.FOLDER :	// internal binary folder
@@ -1183,31 +1442,31 @@
 									&& sourceAttachment != null 
 									&& !sourceAttachment.isEmpty()
 									&& JavaModel.getTarget(workspaceRoot, sourceAttachment, true) == null){
-									return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.toString(), projectName})); //$NON-NLS-1$
+									return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toString(), projectName})); 
 								}
 						}
 					} else if (target instanceof File){
 					    File file = (File) target;
 					    if (!file.isFile()) {
-							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalExternalFolder", path.toOSString(), projectName)); //$NON-NLS-1$
+							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalExternalFolder, new String[] {path.toOSString(), projectName})); 
 					    } else if (!org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(file.getName())) {
-							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalLibraryArchive", path.toOSString(), projectName)); //$NON-NLS-1$
+							return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryArchive, (new String[] {path.toOSString(), projectName}))); 
 					    } else if (checkSourceAttachment 
 								&& sourceAttachment != null 
 								&& !sourceAttachment.isEmpty()
 								&& JavaModel.getTarget(workspaceRoot, sourceAttachment, true) == null){
-								return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.toOSString(), projectName})); //$NON-NLS-1$
+								return  new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceAttachment, new String [] {sourceAttachment.toString(), path.toOSString(), projectName})); 
 					    }
 					} else {
 						boolean isExternal = path.getDevice() != null || !workspaceRoot.getProject(path.segment(0)).exists();
 						if (isExternal) {
-							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundLibrary", path.toOSString(), projectName)); //$NON-NLS-1$
+							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibrary, new String[] {path.toOSString(), projectName})); 
 						} else {
-							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundLibrary", entryPathMsg, projectName)); //$NON-NLS-1$
+							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundLibrary, new String[] {entryPathMsg, projectName})); 
 						}
 					}
 				} else {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalLibraryPath", entryPathMsg, projectName)); //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalLibraryPath, new String[] {entryPathMsg, projectName})); 
 				}
 				break;
 	
@@ -1218,10 +1477,10 @@
 					IJavaProject prereqProject = JavaCore.create(prereqProjectRsc);
 					try {
 						if (!prereqProjectRsc.exists() || !prereqProjectRsc.hasNature(JavaCore.NATURE_ID)){
-							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundProject", path.segment(0), projectName)); //$NON-NLS-1$
+							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundProject, new String[] {path.segment(0), projectName})); 
 						}
 						if (!prereqProjectRsc.isOpen()){
-							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.closedProject", path.segment(0))); //$NON-NLS-1$
+							return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_closedProject, new String[] {path.segment(0)})); 
 						}
 						if (project.getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true) != JavaCore.IGNORE) {
 							long projectTargetJDK = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true));
@@ -1231,10 +1490,10 @@
 							}
 						}
 					} catch (CoreException e){
-						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundProject", path.segment(0), projectName)); //$NON-NLS-1$
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundProject, new String[] {path.segment(0), projectName})); 
 					}
 				} else {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalProjectPath", path.segment(0), projectName)); //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalProjectPath, new String[] {path.segment(0), projectName})); 
 				}
 				break;
 	
@@ -1251,10 +1510,10 @@
 				if (path != null && path.isAbsolute() && !path.isEmpty()) {
 					IPath projectPath= project.getProject().getFullPath();
 					if (!projectPath.isPrefixOf(path) || JavaModel.getTarget(workspaceRoot, path, true) == null){
-						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceFolder", entryPathMsg, projectName)); //$NON-NLS-1$
+						return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_unboundSourceFolder, new String[] {entryPathMsg, projectName})); 
 					}
 				} else {
-					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalSourceFolderPath", entryPathMsg, projectName)); //$NON-NLS-1$
+					return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Messages.bind(Messages.classpath_illegalSourceFolderPath, new String[] {entryPathMsg, projectName})); 
 				}
 				break;
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java
index b15ad33..19b321b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -66,7 +67,7 @@
 	 */
 	protected void executeOperation() throws JavaModelException {
 		try {
-			beginTask(Util.bind("workingCopy.commit"), 2); //$NON-NLS-1$
+			beginTask(Messages.workingCopy_commit, 2); 
 			CompilationUnit workingCopy = getCompilationUnit();
 			IFile resource = (IFile)workingCopy.getResource();
 			ICompilationUnit primary = workingCopy.getPrimary();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
index b3c8c02..e320905 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,7 +18,6 @@
 import org.eclipse.jdt.core.compiler.*;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.IProblemFactory;
 import org.eclipse.jdt.internal.compiler.SourceElementParser;
@@ -27,12 +26,19 @@
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
  * @see ICompilationUnit
  */
 public class CompilationUnit extends Openable implements ICompilationUnit, org.eclipse.jdt.internal.compiler.env.ICompilationUnit, SuffixConstants {
+	/**
+	 * Internal synonynm for deprecated constant AST.JSL2
+	 * to alleviate deprecation warnings.
+	 * @deprecated
+	 */
+	/*package*/ static final int JLS2_INTERNAL = AST.JLS2;
 	
 	protected String name;
 	public WorkingCopyOwner owner;
@@ -106,12 +112,20 @@
 	boolean computeProblems = JavaProject.hasJavaNature(project.getProject()) && perWorkingCopyInfo != null && perWorkingCopyInfo.isActive();
 	IProblemFactory problemFactory = new DefaultProblemFactory();
 	Map options = project.getOptions(true);
+	if (!computeProblems) {
+		// disable task tags checking to speed up parsing
+		options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+	}
+	boolean createAST = info instanceof ASTHolderCUInfo;
 	SourceElementParser parser = new SourceElementParser(
 		requestor, 
 		problemFactory, 
 		new CompilerOptions(options),
-		true/*report local declarations*/);
+		true/*report local declarations*/,
+		!createAST /*optimize string literals only if not creating a DOM AST*/);
 	parser.reportOnlyOneSyntaxError = !computeProblems;
+	if (!computeProblems && !createAST) // disable javadoc parsing if not computing problems and not creating ast
+		parser.javadocParser.checkDocComment = false;
 	requestor.parser = parser;
 	CompilationUnitDeclaration unit = parser.parseCompilationUnit(new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() {
 			public char[] getContents() {
@@ -139,13 +153,13 @@
 	try {
 		if (computeProblems){
 			perWorkingCopyInfo.beginReporting();
-			compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner, perWorkingCopyInfo, false/*don't cleanup cu*/, pm);
+			compilationUnitDeclaration = CompilationUnitProblemFinder.process(unit, this, contents, parser, this.owner, perWorkingCopyInfo, !createAST/*reset env if not creating AST*/, pm);
 			perWorkingCopyInfo.endReporting();
 		}
 		
-		if (info instanceof ASTHolderCUInfo) {
+		if (createAST) {
 			int astLevel = ((ASTHolderCUInfo) info).astLevel;
-			org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, computeProblems, this.owner, pm);
+			org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, computeProblems, this, pm);
 			((ASTHolderCUInfo) info).ast = cu;
 		}
 	} finally {
@@ -318,7 +332,7 @@
  */
 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (container == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullContainer); 
 	}
 	IJavaElement[] elements = new IJavaElement[] {this};
 	IJavaElement[] containers = new IJavaElement[] {container};
@@ -424,35 +438,6 @@
 	CompilationUnit other = (CompilationUnit)obj;
 	return this.owner.equals(other.owner) && super.equals(obj);
 }
-/**
- * @see JavaElement#equalsDOMNode(IDOMNode)
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	String elementName = getElementName();
-	if (node.getNodeType() == IDOMNode.COMPILATION_UNIT && elementName != null ) {
-		String nodeName = node.getName();
-		if (nodeName == null) return false;		
-		if (elementName.equals(nodeName)) {
-			return true;
-		} else {
-			try {
-				// iterate through all the types inside the receiver and see if one of them can fit
-				IType[] types = getTypes();
-				String typeNodeName = nodeName.substring(0, nodeName.lastIndexOf('.'));
-				for (int i = 0, max = types.length; i < max; i++) {
-					if (types[i].getElementName().equals(typeNodeName)) {
-						return true;
-					}
-				}
-			} catch (JavaModelException e) {
-				return false;
-			}
-		}
-	}
-	return false;
-}
 public boolean exists() {
 	// working copy always exists in the model until it is gotten rid of (even if not on classpath)
 	if (getPerWorkingCopyInfo() != null) return true;	
@@ -672,7 +657,7 @@
  * @see ICompilationUnit#getImport(String)
  */
 public IImportDeclaration getImport(String importName) {
-	return new ImportDeclaration((ImportContainer)getImportContainer(), importName);
+	return getImportContainer().getImport(importName);
 }
 /**
  * @see ICompilationUnit#getImportContainer()
@@ -703,10 +688,7 @@
  * @see org.eclipse.jdt.internal.compiler.env.ICompilationUnit#getMainTypeName()
  */
 public char[] getMainTypeName(){
-	String elementName = getElementName();
-	//remove the .java
-	elementName = elementName.substring(0, elementName.length() - 5);
-	return elementName.toCharArray();
+	return Util.getNameWithoutJavaLikeExtension(getElementName()).toCharArray();
 }
 /**
  * @see IWorkingCopy#getOriginal(IJavaElement)
@@ -921,14 +903,6 @@
 public boolean isConsistent() {
 	return JavaModelManager.getJavaModelManager().getElementsOutOfSynchWithBuffers().get(this) == null;
 }
-/**
- * 
- * @see IOpenable
- */
-public boolean isOpen() {
-	Object info = JavaModelManager.getJavaModelManager().getInfo(this);
-	return info != null && ((CompilationUnitElementInfo)info).isOpen();
-}
 public boolean isPrimary() {
 	return this.owner == DefaultWorkingCopyOwner.PRIMARY;
 }
@@ -992,7 +966,7 @@
  */
 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (container == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullContainer); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] containers= new IJavaElement[] {container};
@@ -1049,18 +1023,11 @@
 	
 	return buffer;
 }
-/*
- * @see Openable#openParent
- */
 protected void openParent(Object childInfo, HashMap newElements, IProgressMonitor pm) throws JavaModelException {
-	try {
+	if (!isWorkingCopy())
 		super.openParent(childInfo, newElements, pm);
-	} catch(JavaModelException e){
-		// allow parent to not exist for working copies defined outside classpath
-		if (!isWorkingCopy() && !e.isDoesNotExist()){ 
-			throw e;
-		}
-	}
+	// don't open parent for a working copy to speed up the first becomeWorkingCopy
+	// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89411)
 }
 /**
  * @see ICompilationUnit#reconcile()
@@ -1091,20 +1058,29 @@
 	if (!isWorkingCopy()) return null; // Reconciling is not supported on non working copies
 	if (workingCopyOwner == null) workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY;
 	
+	
 	boolean createAST = false;
-	if (astLevel == AST.JLS2) {
-		// client asking for level 2 AST; these are supported
-		createAST = true;
-	} else if (astLevel == AST.JLS3) {
-		// client asking for level 3 ASTs; these are supported
-		createAST = true;
-	} else {
-		// client asking for no AST (0) or unknown ast level
-		// either way, request denied
-		createAST = false;
+	switch(astLevel) {
+		case JLS2_INTERNAL :
+		case AST.JLS3 :
+			// client asking for level 2 or level 3 ASTs; these are supported
+			createAST = true;
+			break;
+		default:
+			// client asking for no AST (0) or unknown ast level
+			// either way, request denied
+			createAST = false;
+	}
+	PerformanceStats stats = null;
+	if(ReconcileWorkingCopyOperation.PERF) {
+		stats = PerformanceStats.getStats(JavaModelManager.RECONCILE_PERF, this);
+		stats.startRun(new String(this.getFileName()));
 	}
 	ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, createAST, astLevel, forceProblemDetection, workingCopyOwner);
 	op.runOperation(monitor);
+	if(ReconcileWorkingCopyOperation.PERF) {
+		stats.endRun();
+	}
 	return op.ast;
 }
 
@@ -1113,7 +1089,7 @@
  */
 public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (newName == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullName); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] dests= new IJavaElement[] {this.getParent()};
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java
index 7a360af..3712b68 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -49,9 +49,6 @@
 protected ISourceRange getSourceRange() {
 	return new SourceRange(0, this.sourceLength);
 }
-protected boolean isOpen() {
-	return true;
-}
 /**
  * Sets the length of the source string.
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java
index 0646210..ad0b386 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitProblemFinder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -136,7 +136,7 @@
 		Parser parser,
 		WorkingCopyOwner workingCopyOwner,
 		IProblemRequestor problemRequestor,
-		boolean cleanupCU,
+		boolean resetEnvironment,
 		IProgressMonitor monitor)
 		throws JavaModelException {
 
@@ -180,8 +180,10 @@
 					true); // generate code
 			}
 			reportProblems(unit, problemRequestor, monitor);
-			if (NameLookup.VERBOSE)
+			if (NameLookup.VERBOSE) {
 				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+				System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+			}
 			return unit;
 		} catch (OperationCanceledException e) {
 			throw e;
@@ -194,9 +196,8 @@
 				environment.monitor = null; // don't hold a reference to this external object
 			if (problemFactory != null)
 				problemFactory.monitor = null; // don't hold a reference to this external object
-			if (cleanupCU && unit != null)
-				unit.cleanUp();
-			if (problemFinder != null)
+			// NB: unit.cleanUp() is done by caller
+			if (problemFinder != null && resetEnvironment)
 				problemFinder.lookupEnvironment.reset();			
 		}
 	}
@@ -206,11 +207,11 @@
 		char[] contents,
 		WorkingCopyOwner workingCopyOwner,
 		IProblemRequestor problemRequestor,
-		boolean cleanupCU,
+		boolean resetEnvironment,
 		IProgressMonitor monitor)
 		throws JavaModelException {
 			
-		return process(null/*no CompilationUnitDeclaration*/, unitElement, contents, null/*use default Parser*/, workingCopyOwner, problemRequestor, cleanupCU, monitor);
+		return process(null/*no CompilationUnitDeclaration*/, unitElement, contents, null/*use default Parser*/, workingCopyOwner, problemRequestor, resetEnvironment, monitor);
 	}
 
 	
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java
index 7115f21..a455ef8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -68,19 +68,6 @@
 	protected Stack handleStack;
 
 	/**
-	 * The name of the source file being parsed.
-	 */
-	protected char[] sourceFileName= null;
-
-	/**
-	 * The dot-separated name of the package the compilation unit
-	 * is contained in - based on the package statement in the
-	 * compilation unit, and initialized by #acceptPackage.
-	 * Initialized to <code>null</code> for the default package.
-	 */
-	protected char[] packageName= null;
-
-	/**
 	 * The number of references reported thus far. Used to
 	 * expand the arrays of reference kinds and names.
 	 */
@@ -111,7 +98,6 @@
 	this.unit = unit;
 	this.unitInfo = unitInfo;
 	this.newElements = newElements;
-	this.sourceFileName= unit.getPath().toString().toCharArray();
 } 
 /**
  * @see ISourceElementRequestor
@@ -132,23 +118,14 @@
 		this.newElements.put(importContainer, this.importContainerInfo);
 	}
 	
-	// tack on the '.*' if it is onDemand
-	String importName;
-	if (onDemand) {
-		importName= new String(name) + ".*"; //$NON-NLS-1$
-	} else {
-		importName= new String(name);
-	}
-	
-	ImportDeclaration handle = new ImportDeclaration(importContainer, importName);
+	String elementName = JavaModelManager.getJavaModelManager().intern(new String(name));
+	ImportDeclaration handle = new ImportDeclaration(importContainer, elementName, onDemand);
 	resolveDuplicates(handle);
 	
 	ImportDeclarationElementInfo info = new ImportDeclarationElementInfo();
 	info.setSourceRangeStart(declarationStart);
 	info.setSourceRangeEnd(declarationEnd);
 	info.setFlags(modifiers);
-	info.name  = name; // no trailing * if onDemand
-	info.setOnDemand(onDemand);
 
 	this.importContainerInfo.addChild(handle);
 	this.newElements.put(handle, info);
@@ -171,7 +148,6 @@
 		JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek();
 		JavaElement parentHandle= (JavaElement) this.handleStack.peek();
 		PackageDeclaration handle = null;
-		this.packageName= name;
 		
 		if (parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT) {
 			handle = new PackageDeclaration((CompilationUnit) parentHandle, new String(name));
@@ -204,9 +180,10 @@
 	int n = typeNames.length;
 	if (n == 0)
 		return NO_STRINGS;
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
 	String[] typeSigs = new String[n];
 	for (int i = 0; i < n; ++i) {
-		typeSigs[i] = Signature.createTypeSignature(typeNames[i], false);
+		typeSigs[i] = manager.intern(Signature.createTypeSignature(typeNames[i], false));
 	}
 	return typeSigs;
 }
@@ -233,9 +210,9 @@
 	SourceTypeElementInfo parentInfo = (SourceTypeElementInfo) this.infoStack.peek();
 	JavaElement parentHandle= (JavaElement) this.handleStack.peek();
 	SourceField handle = null;
-	
 	if (parentHandle.getElementType() == IJavaElement.TYPE) {
-		handle = new SourceField(parentHandle, new String(fieldInfo.name));
+		String fieldName = JavaModelManager.getJavaModelManager().intern(new String(fieldInfo.name));
+		handle = new SourceField(parentHandle, fieldName);
 	}
 	else {
 		Assert.isTrue(false); // Should not happen
@@ -243,12 +220,12 @@
 	resolveDuplicates(handle);
 	
 	SourceFieldElementInfo info = new SourceFieldElementInfo();
-	info.fieldName = fieldInfo.name;
 	info.setNameSourceStart(fieldInfo.nameSourceStart);
 	info.setNameSourceEnd(fieldInfo.nameSourceEnd);
 	info.setSourceRangeStart(fieldInfo.declarationStart);
 	info.setFlags(fieldInfo.modifiers);
-	info.setTypeName(fieldInfo.type);
+	char[] typeName = JavaModelManager.getJavaModelManager().intern(fieldInfo.type);
+	info.setTypeName(typeName);
 	
 	this.unitInfo.addAnnotationPositions(handle, fieldInfo.annotationPositions);
 
@@ -308,7 +285,8 @@
 	
 	String[] parameterTypeSigs = convertTypeNamesToSigs(methodInfo.parameterTypes);
 	if (parentHandle.getElementType() == IJavaElement.TYPE) {
-		handle = new SourceMethod(parentHandle, new String(methodInfo.name), parameterTypeSigs);
+		String selector = JavaModelManager.getJavaModelManager().intern(new String(methodInfo.name));
+		handle = new SourceMethod(parentHandle, selector, parameterTypeSigs);
 	}
 	else {
 		Assert.isTrue(false); // Should not happen
@@ -324,14 +302,20 @@
 		info = new SourceMethodInfo();
 	info.setSourceRangeStart(methodInfo.declarationStart);
 	int flags = methodInfo.modifiers;
-	info.selector = methodInfo.name;
 	info.setNameSourceStart(methodInfo.nameSourceStart);
 	info.setNameSourceEnd(methodInfo.nameSourceEnd);
 	info.setFlags(flags);
-	info.setArgumentNames(methodInfo.parameterNames);
-	info.setArgumentTypeNames(methodInfo.parameterTypes);
-	info.setReturnType(methodInfo.returnType == null ? new char[]{'v', 'o','i', 'd'} : methodInfo.returnType);
-	info.setExceptionTypeNames(methodInfo.exceptionTypes);
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	char[][] parameterNames = methodInfo.parameterNames;
+	for (int i = 0, length = parameterNames.length; i < length; i++)
+		parameterNames[i] = manager.intern(parameterNames[i]);
+	info.setArgumentNames(parameterNames);
+	char[] returnType = methodInfo.returnType == null ? new char[]{'v', 'o','i', 'd'} : methodInfo.returnType;
+	info.setReturnType(manager.intern(returnType));
+	char[][] exceptionTypes = methodInfo.exceptionTypes;
+	info.setExceptionTypeNames(exceptionTypes);
+	for (int i = 0, length = exceptionTypes.length; i < length; i++)
+		exceptionTypes[i] = manager.intern(exceptionTypes[i]);
 	this.unitInfo.addAnnotationPositions(handle, methodInfo.annotationPositions);
 	parentInfo.addChild(handle);
 	this.newElements.put(handle, info);
@@ -363,10 +347,13 @@
 	info.setFlags(typeInfo.modifiers);
 	info.setNameSourceStart(typeInfo.nameSourceStart);
 	info.setNameSourceEnd(typeInfo.nameSourceEnd);
-	info.setSuperclassName(typeInfo.superclass);
-	info.setSuperInterfaceNames(typeInfo.superinterfaces);
-	info.setSourceFileName(this.sourceFileName);
-	info.setPackageName(this.packageName);
+	JavaModelManager manager = JavaModelManager.getJavaModelManager();
+	char[] superclass = typeInfo.superclass;
+	info.setSuperclassName(superclass == null ? null : manager.intern(superclass));
+	char[][] superinterfaces = typeInfo.superinterfaces;
+	for (int i = 0, length = superinterfaces == null ? 0 : superinterfaces.length; i < length; i++)
+		superinterfaces[i] = manager.intern(superinterfaces[i]);
+	info.setSuperInterfaceNames(superinterfaces);
 	parentInfo.addChild(handle);
 	this.unitInfo.addAnnotationPositions(handle, typeInfo.annotationPositions);
 	this.newElements.put(handle, info);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitVisitor.java
index 488ae0d..f61263f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitVisitor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitVisitor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
index e6f0195..54fce6e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyElementsOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -22,9 +22,9 @@
 import org.eclipse.jdt.core.IParent;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * This operation copies/moves a collection of elements from their current
@@ -84,7 +84,7 @@
  * for progress monitoring.
  */
 protected String getMainTaskName() {
-	return Util.bind("operation.copyElementProgress"); //$NON-NLS-1$
+	return Messages.operation_copyElementProgress; 
 }
 /**
  * Returns the nested operation to use for processing this element
@@ -124,34 +124,19 @@
 private String getSourceFor(IJavaElement element) throws JavaModelException {
 	String source = (String) this.sources.get(element);
 	if (source == null && element instanceof IMember) {
-		IMember member = (IMember)element;
-		ICompilationUnit cu = member.getCompilationUnit();
-		String cuSource = cu.getSource();
-		String cuName = cu.getElementName();
-		source = computeSourceForElement(element, cuSource, cuName);
+		source = ((IMember)element).getSource();
 		this.sources.put(element, source);
 	}
 	return source;
 }
 /**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private String computeSourceForElement(IJavaElement element, String cuSource, String cuName) {
-	String source;
-	IDOMCompilationUnit domCU = new DOMFactory().createCompilationUnit(cuSource, cuName);
-	IDOMNode node = ((JavaElement)element).findNode(domCU);
-	source = new String(node.getCharacters());
-	return source;
-}
-/**
  * Returns <code>true</code> if this element is the main type of its compilation unit.
  */
-protected boolean isRenamingMainType(IJavaElement element, IJavaElement dest) {
+protected boolean isRenamingMainType(IJavaElement element, IJavaElement dest) throws JavaModelException {
 	if ((isRename() || getNewNameFor(element) != null)
 		&& dest.getElementType() == IJavaElement.COMPILATION_UNIT) {
 		String typeName = dest.getElementName();
-		typeName = typeName.substring(0, typeName.length() - 5);
+		typeName = org.eclipse.jdt.internal.core.util.Util.getNameWithoutJavaLikeExtension(typeName);
 		return element.getElementName().equals(typeName) && element.getParent().equals(dest);
 	}
 	return false;
@@ -262,12 +247,6 @@
 	if (element.getElementType() < IJavaElement.TYPE)
 		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
 
-	Member localContext;
-	if (element instanceof Member && (localContext = ((Member)element).getOuterMostLocalContext()) != null && localContext != element) {
-		// JDOM doesn't support source manipulation in local/anonymous types
-		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
-	}
-
 	if (element.isReadOnly())
 		error(IJavaModelStatusConstants.READ_ONLY, element);
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java
index 9cf7045..d0698df 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyPackageFragmentRootOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,7 +20,7 @@
 import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 public class CopyPackageFragmentRootOperation extends JavaModelOperation {
 	IPath destination;
@@ -189,21 +189,21 @@
 	protected IClasspathEntry copy(IClasspathEntry entry) throws JavaModelException {
 		switch (entry.getEntryKind()) {
 			case IClasspathEntry.CPE_CONTAINER:
-				return JavaCore.newContainerEntry(entry.getPath(), entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.isExported());
+				return JavaCore.newContainerEntry(entry.getPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
 			case IClasspathEntry.CPE_LIBRARY:
 				try {
-					return JavaCore.newLibraryEntry(this.destination, entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.isExported());
+					return JavaCore.newLibraryEntry(this.destination, entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
 				} catch (Assert.AssertionFailedException e) {
 					IJavaModelStatus status = new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
 					throw new JavaModelException(status);
 				}
 			case IClasspathEntry.CPE_PROJECT:
-				return JavaCore.newProjectEntry(entry.getPath(), entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.isExported());
+				return JavaCore.newProjectEntry(entry.getPath(), entry.getAccessRules(), entry.combineAccessRules(), entry.getExtraAttributes(), entry.isExported());
 			case IClasspathEntry.CPE_SOURCE:
-				return JavaCore.newSourceEntry(this.destination, entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.getOutputLocation());
+				return JavaCore.newSourceEntry(this.destination, entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.getOutputLocation(), entry.getExtraAttributes());
 			case IClasspathEntry.CPE_VARIABLE:
 				try {
-					return JavaCore.newVariableEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getInclusionPatterns(), entry.getExclusionPatterns(), entry.isExported());
+					return JavaCore.newVariableEntry(entry.getPath(), entry.getSourceAttachmentPath(), entry.getSourceAttachmentRootPath(), entry.getAccessRules(), entry.getExtraAttributes(), entry.isExported());
 				} catch (Assert.AssertionFailedException e) {
 					IJavaModelStatus status = new JavaModelStatus(IJavaModelStatusConstants.INVALID_PATH, e.getMessage());
 					throw new JavaModelException(status);
@@ -254,7 +254,7 @@
 					if (foundExistingEntry && (this.updateModelFlags & IPackageFragmentRoot.REPLACE) == 0) {
 						return new JavaModelStatus(
 							IJavaModelStatusConstants.NAME_COLLISION, 
-							Util.bind("status.nameCollision", this.destination.toString())); //$NON-NLS-1$
+							Messages.bind(Messages.status_nameCollision, new String[] {this.destination.toString()})); 
 					}
 				} catch (JavaModelException e) {
 					return e.getJavaModelStatus();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
index 00fa790..386bf5c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
@@ -1,17 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.util.*;
 
 import org.eclipse.core.resources.*;
@@ -19,9 +17,21 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
 
 /**
  * This operation copies/moves/renames a collection of resources from their current
@@ -59,17 +69,10 @@
 	 */
 	protected Map deltasPerProject = new HashMap(1);
 	/**
-	 * The <code>DOMFactory</code> used to manipulate the source code of
+	 * The <code>ASTParser</code> used to manipulate the source code of
 	 * <code>ICompilationUnit</code>.
-	 * @deprecated JDOM is obsolete
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected DOMFactory fFactory;
-	/**
-	 * A collection of renamed compilation units.  These cus do
-	 * not need to be saved as they no longer exist.
-	 */
-	protected ArrayList fRenamedCompilationUnits = null;
+	protected ASTParser parser;
 	/**
 	 * When executed, this operation will copy the given resources to the
 	 * given container.
@@ -85,14 +88,10 @@
 	 */
 	public CopyResourceElementsOperation(IJavaElement[] resourcesToCopy, IJavaElement[] destContainers, boolean force) {
 		super(resourcesToCopy, destContainers, force);
-		initializeDOMFactory();
+		initializeASTParser();
 	}
-	/**
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	private void initializeDOMFactory() {
-		fFactory = new DOMFactory();
+	private void initializeASTParser() {
+		this.parser = ASTParser.newParser(AST.JLS3);
 	}
 	/**
 	 * Returns the children of <code>source</code> which are affected by this operation.
@@ -193,7 +192,7 @@
 	 * @see MultiOperation
 	 */
 	protected String getMainTaskName() {
-		return Util.bind("operation.copyResourceProgress"); //$NON-NLS-1$
+		return Messages.operation_copyResourceProgress; 
 	}
 	/**
 	 * Sets the deltas to register the changes resulting from this operation
@@ -229,7 +228,7 @@
 	private void processCompilationUnitResource(ICompilationUnit source, PackageFragment dest) throws JavaModelException {
 		String newCUName = getNewNameFor(source);
 		String destName = (newCUName != null) ? newCUName : source.getElementName();
-		String newContent = updatedContent(source, dest, newCUName); // null if unchanged
+		ASTRewrite rewrite = updateContent(source, dest, newCUName); // null if unchanged
 	
 		// TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
 		// store encoding (fix bug 66898)
@@ -245,25 +244,27 @@
 		// copy resource
 		IContainer destFolder = (IContainer)dest.getResource(); // can be an IFolder or an IProject
 		IFile destFile = destFolder.getFile(new Path(destName));
+		org.eclipse.jdt.internal.core.CompilationUnit destCU = new org.eclipse.jdt.internal.core.CompilationUnit(dest, destName, DefaultWorkingCopyOwner.PRIMARY);
 		if (!destFile.equals(sourceResource)) {
 			try {
 				if (destFile.exists()) {
-					if (force) {
+					if (this.force) {
 						// we can remove it
 						deleteResource(destFile, IResource.KEEP_HISTORY);
+						destCU.close(); // ensure the in-memory buffer for the dest CU is closed
 					} else {
 						// abort
 						throw new JavaModelException(new JavaModelStatus(
 							IJavaModelStatusConstants.NAME_COLLISION, 
-							Util.bind("status.nameCollision", destFile.getFullPath().toString()))); //$NON-NLS-1$
+							Messages.bind(Messages.status_nameCollision, destFile.getFullPath().toString()))); 
 					}
 				}
-				int flags = force ? IResource.FORCE : IResource.NONE;
+				int flags = this.force ? IResource.FORCE : IResource.NONE;
 				if (this.isMove()) {
 					flags |= IResource.KEEP_HISTORY;
 					sourceResource.move(destFile.getFullPath(), flags, getSubProgressMonitor(1));
 				} else {
-					if (newContent != null) flags |= IResource.KEEP_HISTORY;
+					if (rewrite != null) flags |= IResource.KEEP_HISTORY;
 					sourceResource.copy(destFile.getFullPath(), flags, getSubProgressMonitor(1));
 				}
 				this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
@@ -274,32 +275,12 @@
 			}
 	
 			// update new resource content
-			if (newContent != null){
+			if (rewrite != null){
 				boolean wasReadOnly = destFile.isReadOnly();
 				try {
-					String encoding = null;
-					try {
-						// TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
-						// fix bug 66898
-						if (sourceEncoding != null) destFile.setCharset(sourceEncoding, this.progressMonitor);
-						// end todo
-						encoding = destFile.getCharset();
-					}
-					catch (CoreException ce) {
-						// use no encoding
-					}
-					// when the file was copied, its read-only flag was preserved -> temporary set it to false
-					// note this doesn't interfer with repository providers as this is a new resource that cannot be under
-					// version control yet
-					Util.setReadOnly(destFile, false);
-					
-					destFile.setContents(
-						new ByteArrayInputStream(encoding == null ? newContent.getBytes() : newContent.getBytes(encoding)), 
-						force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
-						getSubProgressMonitor(1));
-				} catch(IOException e) {
-					throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
+					saveContent(dest, destName, rewrite, sourceEncoding, destFile);
 				} catch (CoreException e) {
+					if (e instanceof JavaModelException) throw (JavaModelException) e;
 					throw new JavaModelException(e);
 				} finally {
 					Util.setReadOnly(destFile, wasReadOnly);
@@ -307,46 +288,28 @@
 			}
 		
 			// register the correct change deltas
-			ICompilationUnit destCU = dest.getCompilationUnit(destName);
 			prepareDeltas(source, destCU, isMove());
 			if (newCUName != null) {
 				//the main type has been renamed
-				String oldName = source.getElementName();
-				oldName = oldName.substring(0, oldName.length() - 5);
-				String newName = newCUName;
-				newName = newName.substring(0, newName.length() - 5);
+				String oldName = Util.getNameWithoutJavaLikeExtension(source.getElementName());
+				String newName = Util.getNameWithoutJavaLikeExtension(newCUName);
 				prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove());
 			}
 		} else {
-			if (!force) {
+			if (!this.force) {
 				throw new JavaModelException(new JavaModelStatus(
 					IJavaModelStatusConstants.NAME_COLLISION, 
-					Util.bind("status.nameCollision", destFile.getFullPath().toString()))); //$NON-NLS-1$
+					Messages.bind(Messages.status_nameCollision, (new String[] {destFile.getFullPath().toString()})))); 
 			}
 			// update new resource content
 			// in case we do a saveas on the same resource we have to simply update the contents
 			// see http://dev.eclipse.org/bugs/show_bug.cgi?id=9351
 			try {
-				if (newContent != null){
-					String encoding = null;
-					try {
-						// TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
-						// fix bug 66898
-						if (sourceEncoding != null) destFile.setCharset(sourceEncoding, this.progressMonitor);
-						// end todo
-						encoding = destFile.getCharset();
-					}
-					catch (CoreException ce) {
-						// use no encoding
-					}
-					destFile.setContents(
-						new ByteArrayInputStream(encoding == null ? newContent.getBytes() : newContent.getBytes(encoding)), 
-						force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, 
-						getSubProgressMonitor(1));
+				if (rewrite != null){
+					saveContent(dest, destName, rewrite, sourceEncoding, destFile);
 				}
-			} catch(IOException e) {
-				throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
 			} catch (CoreException e) {
+				if (e instanceof JavaModelException) throw (JavaModelException) e;
 				throw new JavaModelException(e);
 			}
 		}
@@ -402,9 +365,7 @@
 	 *
 	 * @exception JavaModelException if the operation is unable to
 	 * complete
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
 	private void processPackageFragmentResource(PackageFragment source, PackageFragmentRoot root, String newName) throws JavaModelException {
 		try {
 			String[] newFragName = (newName == null) ? source.names : Util.getTrimmedSimpleNames(newName);
@@ -431,18 +392,18 @@
 				}	
 			}
 			boolean containsReadOnlySubPackageFragments = createNeededPackageFragments((IContainer) source.getParent().getResource(), root, newFragName, shouldMoveFolder);
-			boolean sourceIsReadOnly = srcFolder.isReadOnly();
+			boolean sourceIsReadOnly = Util.isReadOnly(srcFolder);
 	
 			// Process resources
 			if (shouldMoveFolder) {
 				// move underlying resource
 				// TODO Revisit once bug 43044 is fixed
 				if (sourceIsReadOnly) {
-					srcFolder.setReadOnly(false);
+					Util.setReadOnly(srcFolder, false);
 				}
 				srcFolder.move(destPath, force, true /* keep history */, getSubProgressMonitor(1));
 				if (sourceIsReadOnly) {
-					srcFolder.setReadOnly(true);
+					Util.setReadOnly(srcFolder, true);
 				}
 				this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
 			} else {
@@ -462,7 +423,7 @@
 								} else {
 									throw new JavaModelException(new JavaModelStatus(
 										IJavaModelStatusConstants.NAME_COLLISION, 
-										Util.bind("status.nameCollision", destinationResource.getFullPath().toString()))); //$NON-NLS-1$
+										Messages.bind(Messages.status_nameCollision, destinationResource.getFullPath().toString()))); 
 								}
 							}
 						}
@@ -478,7 +439,7 @@
 								} else {
 									throw new JavaModelException(new JavaModelStatus(
 										IJavaModelStatusConstants.NAME_COLLISION, 
-										Util.bind("status.nameCollision", destinationResource.getFullPath().toString()))); //$NON-NLS-1$
+										Messages.bind(Messages.status_nameCollision, (new String[] {destinationResource.getFullPath().toString()})))); 
 								}
 							}
 						}
@@ -497,24 +458,19 @@
 						// we only consider potential compilation units
 						ICompilationUnit cu = newFrag.getCompilationUnit(resourceName);
 						if (Util.isExcluded(cu.getPath(), inclusionPatterns, exclusionPatterns, false/*not a folder*/)) continue;
-						IDOMCompilationUnit domCU = fFactory.createCompilationUnit(cu.getSource(), cu.getElementName());
-						if (domCU != null) {
-							updatePackageStatement(domCU, newFragName);
-							IBuffer buffer = cu.getBuffer();
-							if (buffer == null) continue;
-							String bufferContents = buffer.getContents();
-							if (bufferContents == null) continue;
-							String domCUContents = domCU.getContents();
-							String cuContents = null;
-							if (domCUContents != null) {
-								cuContents = Util.normalizeCRs(domCU.getContents(), bufferContents);
-							} else {
-								// See PR http://dev.eclipse.org/bugs/show_bug.cgi?id=11285
-								cuContents = bufferContents;//$NON-NLS-1$
-							}
-							buffer.setContents(cuContents);
-							cu.save(null, false);
-						}
+						this.parser.setSource(cu);
+						CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
+						AST ast = astCU.getAST();
+						ASTRewrite rewrite = ASTRewrite.create(ast);
+						updatePackageStatement(astCU, newFragName, rewrite);
+						IDocument document = getDocument(cu);
+						TextEdit edits = rewrite.rewriteAST(document, null);
+						try {
+							edits.apply(document);
+						} catch (BadLocationException e) {
+							throw new JavaModelException(e, IJavaModelStatusConstants.INVALID_CONTENTS);
+						}			
+						cu.save(null, false);
 					}
 				}
 			}
@@ -530,8 +486,8 @@
 					for (int i = 0, length = remaining.length; i < length; i++) {
 						IResource file = remaining[i];
 						if (file instanceof IFile) {
-							if (file.isReadOnly()) {
-								file.setReadOnly(false);
+							if (Util.isReadOnly(file)) {
+								Util.setReadOnly(file, false);
 							}
 							this.deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY);
 						} else {
@@ -562,71 +518,79 @@
 				IJavaProject destProject = newFrag.getJavaProject();
 				getDeltaFor(destProject).movedTo(newFrag, source);
 			}
-		} catch (DOMException dom) {
-			throw new JavaModelException(dom, IJavaModelStatusConstants.DOM_EXCEPTION);
 		} catch (JavaModelException e) {
 			throw e;
 		} catch (CoreException ce) {
 			throw new JavaModelException(ce);
 		}
 	}
+	private void saveContent(PackageFragment dest, String destName, ASTRewrite rewrite, String sourceEncoding, IFile destFile) throws JavaModelException {
+		try {
+			// TODO (frederic) remove when bug 67606 will be fixed (bug 67823)
+			// fix bug 66898
+			if (sourceEncoding != null) destFile.setCharset(sourceEncoding, this.progressMonitor);
+			// end todo
+		}
+		catch (CoreException ce) {
+			// use no encoding
+		}
+		// when the file was copied, its read-only flag was preserved -> temporary set it to false
+		// note this doesn't interfer with repository providers as this is a new resource that cannot be under
+		// version control yet
+		Util.setReadOnly(destFile, false);
+		ICompilationUnit destCU = dest.getCompilationUnit(destName);
+		IDocument document = getDocument(destCU);
+		TextEdit edits = rewrite.rewriteAST(document, null);
+		try {
+			edits.apply(document);
+		} catch (BadLocationException e) {
+			throw new JavaModelException(e, IJavaModelStatusConstants.INVALID_CONTENTS);
+		}
+		destCU.save(getSubProgressMonitor(1), this.force);
+	}
 	/**
 	 * Updates the content of <code>cu</code>, modifying the type name and/or package
 	 * declaration as necessary.
 	 *
-	 * @return the new source
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
+	 * @return an AST rewrite or null if no rewrite needed
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	private String updatedContent(ICompilationUnit cu, PackageFragment dest, String newName) throws JavaModelException {
+	private ASTRewrite updateContent(ICompilationUnit cu, PackageFragment dest, String newName) throws JavaModelException {
 		String[] currPackageName = ((PackageFragment) cu.getParent()).names;
 		String[] destPackageName = dest.names;
 		if (Util.equalArraysOrNull(currPackageName, destPackageName) && newName == null) {
 			return null; //nothing to change
 		} else {
-			String typeName = cu.getElementName();
-			typeName = typeName.substring(0, typeName.length() - 5);
-			IDOMCompilationUnit cuDOM = null;
-			IBuffer buffer = cu.getBuffer();
-			if (buffer == null) return null;
-			char[] contents = buffer.getCharacters();
-			if (contents == null) return null;
-			cuDOM = fFactory.createCompilationUnit(contents, typeName);
-			updateTypeName(cu, cuDOM, cu.getElementName(), newName);
-			updatePackageStatement(cuDOM, destPackageName);
-			return cuDOM.getContents();
+			// ensure cu is consistent (noop if already consistent)
+			cu.makeConsistent(this.progressMonitor);
+			this.parser.setSource(cu);
+			CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
+			AST ast = astCU.getAST();
+			ASTRewrite rewrite = ASTRewrite.create(ast);
+			updateTypeName(cu, astCU, cu.getElementName(), newName, rewrite);
+			updatePackageStatement(astCU, destPackageName, rewrite);
+			return rewrite;
 		}
 	}
-	/**
-	 * Makes sure that <code>cu</code> declares to be in the <code>pkgName</code> package.
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	private void updatePackageStatement(IDOMCompilationUnit domCU, String[] pkgName) {
+	private void updatePackageStatement(CompilationUnit astCU, String[] pkgName, ASTRewrite rewriter) throws JavaModelException {
 		boolean defaultPackage = pkgName.length == 0;
-		boolean seenPackageNode = false;
-		Enumeration nodes = domCU.getChildren();
-		while (nodes.hasMoreElements()) {
-			IDOMNode node = (IDOMNode) nodes.nextElement();
-			if (node.getNodeType() == IDOMNode.PACKAGE) {
-				if (! defaultPackage) {
-					node.setName(Util.concatWith(pkgName, '.'));
-				} else {
-					node.remove();
-				}
-				seenPackageNode = true;
-				break;
+		AST ast = astCU.getAST();
+		if (defaultPackage) {
+			// remove existing package statement
+			if (astCU.getPackage() != null)
+				rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, null, null);
+		} else {
+			org.eclipse.jdt.core.dom.PackageDeclaration pkg = astCU.getPackage();
+			if (pkg != null) {
+				// rename package statement
+				Name name = ast.newName(pkgName);
+				rewriter.set(pkg, PackageDeclaration.NAME_PROPERTY, name, null);
+			} else {
+				// create new package statement
+				pkg = ast.newPackageDeclaration();
+				pkg.setName(ast.newName(pkgName));
+				rewriter.set(astCU, CompilationUnit.PACKAGE_PROPERTY, pkg, null);
 			}
 		}
-		if (!seenPackageNode && !defaultPackage) {
-			//the cu was in a default package...no package declaration
-			//create the new package declaration as the first child of the cu
-			IDOMPackage pkg = fFactory.createPackage("package " + Util.concatWith(pkgName, '.') + ";" + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR); //$NON-NLS-1$ //$NON-NLS-2$
-			IDOMNode firstChild = domCU.getFirstChild();
-			if (firstChild != null) {
-				firstChild.insertSibling(pkg);
-			} // else the cu was empty: leave it empty
-		}
 	}
 	
 	private void updateReadOnlyPackageFragmentsForCopy(IContainer sourceFolder, IPackageFragmentRoot root, String[] newFragName) {
@@ -654,27 +618,37 @@
 			}
 		}
 	}
-		/**
+			/**
 		 * Renames the main type in <code>cu</code>.
-	     * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
 		 */
-        // TODO - JDOM - remove once model ported off of JDOM
-		private void updateTypeName(ICompilationUnit cu, IDOMCompilationUnit domCU, String oldName, String newName) throws JavaModelException {
+		private void updateTypeName(ICompilationUnit cu, CompilationUnit astCU, String oldName, String newName, ASTRewrite rewriter) throws JavaModelException {
 			if (newName != null) {
-				if (fRenamedCompilationUnits == null) {
-					fRenamedCompilationUnits= new ArrayList(1);
-				}
-				fRenamedCompilationUnits.add(cu);
-				String oldTypeName= oldName.substring(0, oldName.length() - 5);
-				String newTypeName= newName.substring(0, newName.length() - 5);
+				String oldTypeName= Util.getNameWithoutJavaLikeExtension(oldName);
+				String newTypeName= Util.getNameWithoutJavaLikeExtension(newName);
+				AST ast = astCU.getAST();
 				// update main type name
 				IType[] types = cu.getTypes();
 				for (int i = 0, max = types.length; i < max; i++) {
 					IType currentType = types[i];
 					if (currentType.getElementName().equals(oldTypeName)) {
-						IDOMNode typeNode = ((JavaElement) currentType).findNode(domCU);
+						AbstractTypeDeclaration typeNode = (AbstractTypeDeclaration) ((JavaElement) currentType).findNode(astCU);
 						if (typeNode != null) {
-							typeNode.setName(newTypeName);
+							// rename type
+							rewriter.replace(typeNode.getName(), ast.newSimpleName(newTypeName), null);
+							// rename constructors
+							Iterator bodyDeclarations = typeNode.bodyDeclarations().iterator();
+							while (bodyDeclarations.hasNext()) {
+								Object bodyDeclaration = bodyDeclarations.next();
+								if (bodyDeclaration instanceof MethodDeclaration) {
+									MethodDeclaration methodDeclaration = (MethodDeclaration) bodyDeclaration;
+									if (methodDeclaration.isConstructor()) {
+										SimpleName methodName = methodDeclaration.getName();
+										if (methodName.getIdentifier().equals(oldTypeName)) {
+											rewriter.replace(methodName, ast.newSimpleName(newTypeName), null);
+										}
+									}
+								}
+							}
 						}
 					}
 				}
@@ -719,7 +693,7 @@
 		int elementType = element.getElementType();
 	
 		if (elementType == IJavaElement.COMPILATION_UNIT) {
-			CompilationUnit compilationUnit = (CompilationUnit)element;
+			org.eclipse.jdt.internal.core.CompilationUnit compilationUnit = (org.eclipse.jdt.internal.core.CompilationUnit) element;
 			if (isMove() && compilationUnit.isWorkingCopy() && !compilationUnit.isPrimary())
 				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
 		} else if (elementType != IJavaElement.PACKAGE_FRAGMENT) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
index 042e3f7..bf939b6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -33,6 +33,7 @@
 import org.eclipse.jdt.core.JavaConventions;
 //import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -79,7 +80,7 @@
  */
 protected void executeOperation() throws JavaModelException {
 	try {
-		beginTask(Util.bind("operation.createUnitProgress"), 2); //$NON-NLS-1$
+		beginTask(Messages.operation_createUnitProgress, 2); 
 		JavaElementDelta delta = newJavaElementDelta();
 		ICompilationUnit unit = getCompilationUnit();
 		IPackageFragment pkg = (IPackageFragment) getParentElement();
@@ -104,7 +105,7 @@
 			} else {
 				throw new JavaModelException(new JavaModelStatus(
 					IJavaModelStatusConstants.NAME_COLLISION, 
-					Util.bind("status.nameCollision", compilationUnitFile.getFullPath().toString()))); //$NON-NLS-1$
+					Messages.bind(Messages.status_nameCollision, (new String[] {compilationUnitFile.getFullPath().toString()})))); 
 			}
 		} else {
 			try {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java
index 7b73f91..c996a59 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateElementInCUOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,15 +13,23 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IWorkspace;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.jdom.*;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
 import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
 
 /**
  * <p>This abstract class implements behavior common to <code>CreateElementInCUOperations</code>.
@@ -36,11 +44,9 @@
  */
 public abstract class CreateElementInCUOperation extends JavaModelOperation {
 	/**
-	 * The compilation unit DOM used for this operation
-	 * @deprecated JDOM is obsolete
+	 * The compilation unit AST used for this operation
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected IDOMCompilationUnit fCUDOM;
+	protected CompilationUnit cuAST;		
 	/**
 	 * A constant meaning to position the new element
 	 * as the last child of its parent element.
@@ -61,7 +67,7 @@
 	 * One of the position constants, describing where
 	 * to position the newly created element.
 	 */
-	protected int fInsertionPolicy = INSERT_LAST;
+	protected int insertionPolicy = INSERT_LAST;
 	/**
 	 * The element that the newly created element is
 	 * positioned relative to, as described by
@@ -69,30 +75,14 @@
 	 * if the newly created element will be positioned
 	 * last.
 	 */
-	protected IJavaElement fAnchorElement = null;
+	protected IJavaElement anchorElement = null;
 	/**
 	 * A flag indicating whether creation of a new element occurred.
 	 * A request for creating a duplicate element would request in this
 	 * flag being set to <code>false</code>. Ensures that no deltas are generated
 	 * when creation does not occur.
 	 */
-	protected boolean fCreationOccurred = true;
-	/**
-	 * The element that is being created.
-	 * @deprecated JDOM is obsolete
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected DOMNode fCreatedElement;
-	/**
-	 * The position of the element that is being created.
-	 */
-	protected int fInsertionPosition = -1;
-	/**
-	 * The number of characters the new element replaces,
-	 * or 0 if the new element is inserted,
-	 * or -1 if the new element is append to the end of the CU.
-	 */
-	protected int fReplacementLength = -1;
+	protected boolean creationOccurred = true;
 	/**
 	 * Constructs an operation that creates a Java Language Element with
 	 * the specified parent, contained within a compilation unit.
@@ -101,6 +91,14 @@
 		super(null, new IJavaElement[]{parentElement});
 		initializeDefaultPosition();
 	}
+	protected void apply(ASTRewrite rewriter, IDocument document) throws JavaModelException {
+		TextEdit edits = rewriter.rewriteAST(document, null);
+ 		try {
+	 		edits.apply(document);
+ 		} catch (BadLocationException e) {
+ 			throw new JavaModelException(e, IJavaModelStatusConstants.INVALID_CONTENTS);
+ 		}
+	}
 	/**
 	 * Only allow cancelling if this operation is not nested.
 	 */
@@ -136,27 +134,9 @@
 			beginTask(getMainTaskName(), getMainAmountOfWork());
 			JavaElementDelta delta = newJavaElementDelta();
 			ICompilationUnit unit = getCompilationUnit();
-			generateNewCompilationUnitDOM(unit);
-			if (fCreationOccurred) {
+			generateNewCompilationUnitAST(unit);
+			if (this.creationOccurred) {
 				//a change has really occurred
-				IBuffer buffer = unit.getBuffer();
-				if (buffer  == null) return;
-				char[] bufferContents = buffer.getCharacters();
-				if (bufferContents == null) return;
-				char[] elementContents = Util.normalizeCRs(getCreatedElementCharacters(), bufferContents);
-				switch (fReplacementLength) {
-					case -1 : 
-						// element is append at the end
-						buffer.append(elementContents);
-						break;
-					case 0 :
-						// element is inserted
-						buffer.replace(fInsertionPosition, 0, elementContents);
-						break;
-					default :
-						// element is replacing the previous one
-						buffer.replace(fInsertionPosition, fReplacementLength, elementContents);
-				}
 				unit.save(null, false);
 				boolean isWorkingCopy = unit.isWorkingCopy();
 				if (!isWorkingCopy)
@@ -177,37 +157,32 @@
 			done();
 		}
 	}
-	/**
-	 * Returns the current contents of the created document fragment as a
-	 * character array.
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	private char[] getCreatedElementCharacters() {
-		return fCreatedElement.getCharacters();
-	}
-	/**
-	 * Returns a JDOM document fragment for the element being created.
-	 * @deprecated JDOM is obsolete
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected abstract IDOMNode generateElementDOM() throws JavaModelException;
-	/**
-	 * Returns the DOM with the new source to use for the given compilation unit.
-	 * @deprecated JDOM is obsolete
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected void generateNewCompilationUnitDOM(ICompilationUnit cu) throws JavaModelException {
-		IBuffer buffer = cu.getBuffer();
-		if (buffer == null) return;
-		char[] prevSource = buffer.getCharacters();
-		if (prevSource == null) return;
 	
-		// create a JDOM for the compilation unit
-		fCUDOM = (new DOMFactory()).createCompilationUnit(prevSource, cu.getElementName());
-		IDOMNode child = generateElementDOM();
+	/*
+	 * Returns the property descriptor for the element being created.
+	 */
+	protected abstract StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent);
+	
+	/*
+	 * Returns an AST node for the element being created.
+	 */
+	protected abstract ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException;
+	/*
+	 * Generates a new AST for this operation and applies it to the given cu
+	 */
+	protected void generateNewCompilationUnitAST(ICompilationUnit cu) throws JavaModelException {
+		this.cuAST = parse(cu);
+		
+		AST ast = this.cuAST.getAST();
+		ASTRewrite rewriter = ASTRewrite.create(ast);
+		IDocument document = getDocument(cu);
+		ASTNode child = generateElementAST(rewriter, document, cu);
 		if (child != null) {
-			insertDOMNode(fCUDOM, child);
+			ASTNode parent = ((JavaElement) getParentElement()).findNode(this.cuAST);
+			if (parent == null)
+				parent = this.cuAST;
+			insertASTNode(rewriter, parent, child);
+			apply(rewriter, document);
 		}
 		worked(1);
 	}
@@ -256,34 +231,49 @@
 		// last child of the parent element in which it is created.
 	}
 	/**
-	 * Inserts the given child into the given JDOM, 
+	 * Inserts the given child into the given AST, 
 	 * based on the position settings of this operation.
 	 *
 	 * @see #createAfter(IJavaElement)
 	 * @see #createBefore(IJavaElement)
-	 * @deprecated JDOM is obsolete
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected void insertDOMNode(IDOMNode parent, IDOMNode child) {
-		if (fInsertionPolicy != INSERT_LAST) {
-			IDOMNode sibling = ((JavaElement)fAnchorElement).findNode(fCUDOM);
-			if (sibling != null && fInsertionPolicy == INSERT_AFTER) {
-				sibling = sibling.getNextNode();
-			}
-			if (sibling != null) {
-				sibling.insertSibling(child);
-				fCreatedElement = (DOMNode)child;
-				fInsertionPosition = ((DOMNode)sibling).getStartPosition();
-				fReplacementLength = 0;
-				return;
-			}
+	protected void insertASTNode(ASTRewrite rewriter, ASTNode parent, ASTNode child) throws JavaModelException {
+		StructuralPropertyDescriptor propertyDescriptor = getChildPropertyDescriptor(parent);
+		if (propertyDescriptor instanceof ChildListPropertyDescriptor) {
+			ChildListPropertyDescriptor childListPropertyDescriptor = (ChildListPropertyDescriptor) propertyDescriptor;
+	 		ListRewrite rewrite = rewriter.getListRewrite(parent, childListPropertyDescriptor);
+	 		switch (this.insertionPolicy) {
+	 			case INSERT_BEFORE:
+	 				ASTNode element = ((JavaElement) this.anchorElement).findNode(this.cuAST);
+	 				if (childListPropertyDescriptor.getElementType().isAssignableFrom(element.getClass()))
+		 				rewrite.insertBefore(child, element, null);
+	 				else
+	 					// case of an empty import list: the anchor element is the top level type and cannot be used in insertBefore as it is not the same type
+	 					rewrite.insertLast(child, null);
+	 				break;
+	 			case INSERT_AFTER:
+	 				element = ((JavaElement) this.anchorElement).findNode(this.cuAST);
+	 				if (childListPropertyDescriptor.getElementType().isAssignableFrom(element.getClass()))
+		 				rewrite.insertAfter(child, element, null);
+	 				else
+	 					// case of an empty import list: the anchor element is the top level type and cannot be used in insertAfter as it is not the same type
+	 					rewrite.insertLast(child, null);
+	 				break;
+	 			case INSERT_LAST:
+	 				rewrite.insertLast(child, null);
+	 				break;
+	 		}
+		} else {
+			rewriter.set(parent, propertyDescriptor, child, null);
 		}
-		//add as the last element of the parent
-		parent.addChild(child);
-		fCreatedElement = (org.eclipse.jdt.internal.core.jdom.DOMNode)child;
-		fInsertionPosition = ((org.eclipse.jdt.internal.core.jdom.DOMNode)parent).getInsertionPosition();
-	//	fInsertionPosition = lastChild == null ? ((DOMNode)parent).getInsertionPosition() : lastChild.getInsertionPosition();
-		fReplacementLength = parent.getParent() == null ? -1 : 0;
+ 	}
+	protected CompilationUnit parse(ICompilationUnit cu) throws JavaModelException {
+		// ensure cu is consistent (noop if already consistent)
+		cu.makeConsistent(this.progressMonitor);
+		// create an AST for the compilation unit
+		ASTParser parser = ASTParser.newParser(AST.JLS3);
+		parser.setSource(cu);
+		return (CompilationUnit) parser.createAST(this.progressMonitor);
 	}
 	/**
 	 * Sets the name of the <code>DOMNode</code> that will be used to
@@ -302,11 +292,11 @@
 	 */
 	protected void setRelativePosition(IJavaElement sibling, int policy) throws IllegalArgumentException {
 		if (sibling == null) {
-			fAnchorElement = null;
-			fInsertionPolicy = INSERT_LAST;
+			this.anchorElement = null;
+			this.insertionPolicy = INSERT_LAST;
 		} else {
-			fAnchorElement = sibling;
-			fInsertionPolicy = policy;
+			this.anchorElement = sibling;
+			this.insertionPolicy = policy;
 		}
 	}
 	/**
@@ -324,13 +314,13 @@
 		if (getParentElement() == null) {
 			return new JavaModelStatus(IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
 		}
-		if (fAnchorElement != null) {
-			IJavaElement domPresentParent = fAnchorElement.getParent();
+		if (this.anchorElement != null) {
+			IJavaElement domPresentParent = this.anchorElement.getParent();
 			if (domPresentParent.getElementType() == IJavaElement.IMPORT_CONTAINER) {
 				domPresentParent = domPresentParent.getParent();
 			}
 			if (!domPresentParent.equals(getParentElement())) {
-				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, fAnchorElement);
+				return new JavaModelStatus(IJavaModelStatusConstants.INVALID_SIBLING, this.anchorElement);
 			}
 		}
 		return JavaModelStatus.VERIFIED_OK;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
index 43608d8..d75cb9f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateFieldOperation.java
@@ -1,22 +1,28 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * <p>This operation creates a field declaration in a type.
@@ -39,40 +45,23 @@
 public CreateFieldOperation(IType parentElement, String source, boolean force) {
 	super(parentElement, source, force);
 }
-/**
- * @see CreateTypeMemberOperation#generateSyntaxIncorrectDOM()
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateElementDOM() throws JavaModelException {
-	if (fDOMNode == null) {
-		fDOMNode = (new DOMFactory()).createField(fSource);
-		if (fDOMNode == null) {
-			fDOMNode = generateSyntaxIncorrectDOM();
-			if (fDOMNode == null) {
-				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-			}
-		}
-		if (fAlteredName != null && fDOMNode != null) {
-			fDOMNode.setName(fAlteredName);
-		}
-	}
-	if (!(fDOMNode instanceof IDOMField)) {
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, document, cu);
+	if (node.getNodeType() != ASTNode.FIELD_DECLARATION)
 		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-	}
-	return fDOMNode;
+	return node;
 }
 /**
  * @see CreateElementInCUOperation#generateResultHandle
  */
 protected IJavaElement generateResultHandle() {
-	return getType().getField(getDOMNodeName());
+	return getType().getField(getASTNodeName());
 }
 /**
  * @see CreateElementInCUOperation#getMainTaskName()
  */
 public String getMainTaskName(){
-	return Util.bind("operation.createFieldProgress"); //$NON-NLS-1$
+	return Messages.operation_createFieldProgress; 
 }
 /**
  * By default the new field is positioned after the last existing field
@@ -99,19 +88,25 @@
  * @see CreateTypeMemberOperation#verifyNameCollision
  */
 protected IJavaModelStatus verifyNameCollision() {
-	IType type= getType();
-	if (type.getField(getDOMNodeName()).exists()) {
-		return new JavaModelStatus(
-			IJavaModelStatusConstants.NAME_COLLISION, 
-			Util.bind("status.nameCollision", getDOMNodeName())); //$NON-NLS-1$
+	if (this.createdNode != null) {
+		IType type= getType();
+		String fieldName = getASTNodeName();
+		if (type.getField(fieldName).exists()) {
+			return new JavaModelStatus(
+				IJavaModelStatusConstants.NAME_COLLISION, 
+				Messages.bind(Messages.status_nameCollision, fieldName)); 
+		}
 	}
 	return JavaModelStatus.VERIFIED_OK;
 }
-/**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private String getDOMNodeName() {
-	return fDOMNode.getName();
+private String getASTNodeName() {
+	VariableDeclarationFragment fragment = (VariableDeclarationFragment) ((FieldDeclaration) this.createdNode).fragments().iterator().next();
+	return fragment.getName().getIdentifier();
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	VariableDeclarationFragment fragment = (VariableDeclarationFragment) ((FieldDeclaration) node).fragments().iterator().next();
+	SimpleName oldName = fragment.getName();
+	fragment.setName(newName);
+	return oldName;
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java
index 80bbf37..44cc371 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateImportOperation.java
@@ -1,15 +1,17 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import java.util.Iterator;
+
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IImportDeclaration;
@@ -19,8 +21,16 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaConventions;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * <p>This operation adds an import declaration to an existing compilation unit.
@@ -45,44 +55,55 @@
 	/**
 	 * The name of the import to be created.
 	 */
-	protected String fImportName;
+	protected String importName;
 /**
  * When executed, this operation will add an import to the given compilation unit.
  */
 public CreateImportOperation(String importName, ICompilationUnit parentElement) {
 	super(parentElement);
-	fImportName = importName;
+	this.importName = importName;
 }
-/**
- * @see CreateTypeMemberOperation
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateElementDOM() {
-	if (fCUDOM.getChild(fImportName) == null) {
-		DOMFactory factory = new DOMFactory();
-		//not a duplicate
-		IDOMImport imp = factory.createImport();
-		imp.setName(fImportName);
-		return imp;
+protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
+	return CompilationUnit.IMPORTS_PROPERTY;
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
+	// ensure no duplicate
+	Iterator imports = this.cuAST.imports().iterator();
+	while (imports.hasNext()) {
+		ImportDeclaration importDeclaration = (ImportDeclaration) imports.next();
+		if (this.importName.equals(importDeclaration.getName().getFullyQualifiedName())) {
+			//no new import was generated
+			this.creationOccurred = false;
+			return null;
+		}
 	}
 	
-	//no new import was generated
-	fCreationOccurred = false;
-	//all the work has already been done
-	return null;
+	AST ast = this.cuAST.getAST();
+	ImportDeclaration importDeclaration = ast.newImportDeclaration();
+	// split import name into individual fragments, checking for on demand imports
+	boolean onDemand = this.importName.endsWith("*"); //$NON-NLS-1$
+	char[][] charFragments = CharOperation.splitOn('.', this.importName.toCharArray(), 0, onDemand ? this.importName.length()-2 : this.importName.length());
+	int length = charFragments.length;
+	String[] strFragments = new String[length];
+	for (int i = 0; i < length; i++) {
+		strFragments[i] = String.valueOf(charFragments[i]);
+	}
+	Name name = ast.newName(strFragments);
+	importDeclaration.setName(name);
+	if (onDemand) importDeclaration.setOnDemand(true);
+	return importDeclaration;
 }
 /**
  * @see CreateElementInCUOperation#generateResultHandle
  */
 protected IJavaElement generateResultHandle() {
-	return getCompilationUnit().getImport(fImportName);
+	return getCompilationUnit().getImport(this.importName);
 }
 /**
  * @see CreateElementInCUOperation#getMainTaskName()
  */
 public String getMainTaskName(){
-	return Util.bind("operation.createImportsProgress"); //$NON-NLS-1$
+	return Messages.operation_createImportsProgress; 
 }
 /**
  * Sets the correct position for the new import:<ul>
@@ -130,8 +151,8 @@
 	if (!status.isOK()) {
 		return status;
 	}
-	if (JavaConventions.validateImportDeclaration(fImportName).getSeverity() == IStatus.ERROR) {
-		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, fImportName);
+	if (JavaConventions.validateImportDeclaration(this.importName).getSeverity() == IStatus.ERROR) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, this.importName);
 	}
 	return JavaModelStatus.VERIFIED_OK;
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java
index e921420..a6a03ae 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateInitializerOperation.java
@@ -1,21 +1,25 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * <p>This operation creates a initializer in a type.
@@ -31,7 +35,7 @@
 	 * The current number of initializers in the parent type.
 	 * Used to retrieve the handle of the newly created initializer.
 	 */
-	protected int fNumberOfInitializers= 1;
+	protected int numberOfInitializers= 1;
 /**
  * When executed, this operation will create an initializer with the given name
  * in the given type with the specified source.
@@ -43,25 +47,11 @@
 public CreateInitializerOperation(IType parentElement, String source) {
 	super(parentElement, source, false);
 }
-/**
- * @see CreateTypeMemberOperation#generateSyntaxIncorrectDOM()
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateElementDOM() throws JavaModelException {
-	if (fDOMNode == null) {
-		fDOMNode = (new DOMFactory()).createInitializer(fSource);
-		if (fDOMNode == null) {
-			fDOMNode = generateSyntaxIncorrectDOM();
-			if (fDOMNode == null) {
-				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-			}
-		}
-	}					
-	if (!(fDOMNode instanceof IDOMInitializer)) {
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, document, cu);
+	if (node.getNodeType() != ASTNode.INITIALIZER)
 		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-	}
-	return fDOMNode;
+	return node;
 }
 /**
  * @see CreateElementInCUOperation#generateResultHandle
@@ -70,15 +60,15 @@
 	try {
 		//update the children to be current
 		getType().getCompilationUnit().close();
-		if (fAnchorElement == null) {
-			return getType().getInitializer(fNumberOfInitializers);
+		if (this.anchorElement == null) {
+			return getType().getInitializer(this.numberOfInitializers);
 		} else {
 			IJavaElement[] children = getType().getChildren();
 			int count = 0;
 			for (int i = 0; i < children.length; i++) {
 				IJavaElement child = children[i];
-				if (child.equals(fAnchorElement)) {
-					if (child .getElementType() == IJavaElement.INITIALIZER && fInsertionPolicy == CreateElementInCUOperation.INSERT_AFTER) {
+				if (child.equals(this.anchorElement)) {
+					if (child .getElementType() == IJavaElement.INITIALIZER && this.insertionPolicy == CreateElementInCUOperation.INSERT_AFTER) {
 						count++;
 					}
 					return getType().getInitializer(count);
@@ -97,7 +87,10 @@
  * @see CreateElementInCUOperation#getMainTaskName()
  */
 public String getMainTaskName(){
-	return Util.bind("operation.createInitializerProgress"); //$NON-NLS-1$
+	return Messages.operation_createInitializerProgress; 
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	return null; // intializer cannot be renamed
 }
 /**
  * By default the new initializer is positioned after the last existing initializer
@@ -109,7 +102,7 @@
 	try {
 		IJavaElement[] elements = parentElement.getInitializers();
 		if (elements != null && elements.length > 0) {
-			fNumberOfInitializers= elements.length;
+			this.numberOfInitializers = elements.length;
 			createAfter(elements[elements.length - 1]);
 		} else {
 			elements = parentElement.getChildren();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
index 322e3d6..c0bfdf1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateMethodOperation.java
@@ -1,23 +1,32 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.Signature;
-import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * <p>This operation creates an instance method. 
@@ -29,7 +38,9 @@
  * </ul>
  */
 public class CreateMethodOperation extends CreateTypeMemberOperation {
-	protected String[] fParameterTypes;
+	
+	protected String[] parameterTypes;
+	
 /**
  * When executed, this operation will create a method
  * in the given type with the specified source.
@@ -39,108 +50,71 @@
 }
 /**
  * Returns the type signatures of the parameter types of the
- * current <code>DOMMethod</code>
- * @deprecated JDOM is obsolete
+ * current <code>MethodDeclaration</code>
  */
-// TODO - JDOM - remove once model ported off of JDOM
-protected String[] convertDOMMethodTypesToSignatures() {
-	if (fParameterTypes == null) {
-		if (isDOMNodeNull()) {
-			String[] domParameterTypes = ((IDOMMethod)fDOMNode).getParameterTypes();
-			if (domParameterTypes != null) {
-				fParameterTypes = new String[domParameterTypes.length];
-				// convert the DOM types to signatures
-				int i;
-				for (i = 0; i < fParameterTypes.length; i++) {
-					fParameterTypes[i] = Signature.createTypeSignature(domParameterTypes[i].toCharArray(), false);
-				}
+protected String[] convertASTMethodTypesToSignatures() {
+	if (this.parameterTypes == null) {
+		if (this.createdNode != null) {
+			List parameters = ((MethodDeclaration) this.createdNode).parameters();
+			int size = parameters.size();
+			this.parameterTypes = new String[size];
+			Iterator iterator = parameters.iterator();
+			// convert the AST types to signatures
+			for (int i = 0; i < size; i++) {
+				SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
+				this.parameterTypes[i] = Util.getSignature(parameter.getType());
 			}
 		}
 	}
-	return fParameterTypes;
+	return this.parameterTypes;
 }
-/**
- * @see CreateTypeMemberOperation#generateSyntaxIncorrectDOM()
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateElementDOM() throws JavaModelException {
-	if (fDOMNode == null) {
-		fDOMNode = (new DOMFactory()).createMethod(fSource);
-		if (fDOMNode == null) {
-			//syntactically incorrect source
-			fDOMNode = generateSyntaxIncorrectDOM();
-			if (fDOMNode == null) {
-				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-			}
-		}
-		if (fAlteredName != null && isDOMNodeNull()) {
-			fDOMNode.setName(fAlteredName);
-		}
-	}
-	if (!(fDOMNode instanceof IDOMMethod)) {
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, document, cu);
+	if (node.getNodeType() != ASTNode.METHOD_DECLARATION)
 		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-	}
-	return fDOMNode;
+	return node;
 }
 /**
  * @see CreateElementInCUOperation#generateResultHandle
  */
 protected IJavaElement generateResultHandle() {
-	String[] types = convertDOMMethodTypesToSignatures();
-	String name = computeName();
+	String[] types = convertASTMethodTypesToSignatures();
+	String name = getASTNodeName();
 	return getType().getMethod(name, types);
 }
-/**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private String computeName() {
-	String name;
-	if (((IDOMMethod) fDOMNode).isConstructor()) {
-		name = fDOMNode.getParent().getName();
-	} else {
-		name = getDOMNodeName();
-	}
-	return name;
-}
-/**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private String getDOMNodeName() {
-	return fDOMNode.getName();
+private String getASTNodeName() {
+	return ((MethodDeclaration) this.createdNode).getName().getIdentifier();
 }
 /**
  * @see CreateElementInCUOperation#getMainTaskName()
  */
 public String getMainTaskName(){
-	return Util.bind("operation.createMethodProgress"); //$NON-NLS-1$
+	return Messages.operation_createMethodProgress; 
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	MethodDeclaration method = (MethodDeclaration) node;
+	SimpleName oldName = method.getName();
+	method.setName(newName);
+	return oldName;
 }
 /**
  * @see CreateTypeMemberOperation#verifyNameCollision
  */
 protected IJavaModelStatus verifyNameCollision() {
-	if (isDOMNodeNull()) {
+	if (this.createdNode != null) {
 		IType type = getType();
-		String name = getDOMNodeName();
-		if (name == null) { //constructor
+		String name;
+		if (((MethodDeclaration) this.createdNode).isConstructor())
 			name = type.getElementName();
-		}
-		String[] types = convertDOMMethodTypesToSignatures();
+		else
+			name = getASTNodeName();
+		String[] types = convertASTMethodTypesToSignatures();
 		if (type.getMethod(name, types).exists()) {
 			return new JavaModelStatus(
 				IJavaModelStatusConstants.NAME_COLLISION, 
-				Util.bind("status.nameCollision", name)); //$NON-NLS-1$
+				Messages.bind(Messages.status_nameCollision, name)); 
 		}
 	}
 	return JavaModelStatus.VERIFIED_OK;
 }
-/**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private boolean isDOMNodeNull() {
-	return fDOMNode != null;
-}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java
index 8c4474d..9265806 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageDeclarationOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,13 +16,18 @@
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
-import org.eclipse.jdt.core.IPackageDeclaration;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaConventions;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.jdom.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * <p>This operation adds/replaces a package declaration in an existing compilation unit.
@@ -38,57 +43,44 @@
 	/**
 	 * The name of the package declaration being created
 	 */
-	protected String fName = null;
+	protected String name = null;
 /**
  * When executed, this operation will add a package declaration to the given compilation unit.
  */
 public CreatePackageDeclarationOperation(String name, ICompilationUnit parentElement) {
 	super(parentElement);
-	fName= name;
+	this.name= name;
 }
-/**
- * @see CreateTypeMemberOperation#generateSyntaxIncorrectDOM()
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateElementDOM() throws JavaModelException {
-	IJavaElement[] children = getCompilationUnit().getChildren();
+protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
+	return CompilationUnit.PACKAGE_PROPERTY;
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
 	//look for an existing package declaration
+	IJavaElement[] children = getCompilationUnit().getChildren();
 	for (int i = 0; i < children.length; i++) {
-		if (children[i].getElementType() ==  IJavaElement.PACKAGE_DECLARATION) {
-			IPackageDeclaration pck = (IPackageDeclaration) children[i];
-			IDOMPackage pack = (IDOMPackage) ((JavaElement)pck).findNode(fCUDOM);
-			if (!pack.getName().equals(fName)) {
-				 // get the insertion position before setting the name, as this makes it a detailed node
-				 // thus the start position is always 0
-				DOMNode node = (org.eclipse.jdt.internal.core.jdom.DOMNode)pack;
-				fInsertionPosition = node.getStartPosition();
-				fReplacementLength = node.getEndPosition() - fInsertionPosition + 1;
-				pack.setName(fName);
-				fCreatedElement = (org.eclipse.jdt.internal.core.jdom.DOMNode)pack;
-			} else {
-				//equivalent package declaration already exists
-				fCreationOccurred= false;
-			}
-			
+		if (children[i].getElementType() ==  IJavaElement.PACKAGE_DECLARATION && this.name.equals(children[i].getElementName())) {
+			//equivalent package declaration already exists
+			this.creationOccurred = false;
 			return null;
 		}
 	}
-	IDOMPackage pack = (new DOMFactory()).createPackage();
-	pack.setName(fName);
-	return pack;
+	AST ast = this.cuAST.getAST();
+	PackageDeclaration pkgDeclaration = ast.newPackageDeclaration();
+	Name astName = ast.newName(this.name);
+	pkgDeclaration.setName(astName);
+	return pkgDeclaration;
 }
 /**
  * Creates and returns the handle for the element this operation created.
  */
 protected IJavaElement generateResultHandle() {
-	return getCompilationUnit().getPackageDeclaration(fName);
+	return getCompilationUnit().getPackageDeclaration(this.name);
 }
 /**
  * @see CreateElementInCUOperation#getMainTaskName()
  */
 public String getMainTaskName(){
-	return Util.bind("operation.createPackageProgress"); //$NON-NLS-1$
+	return Messages.operation_createPackageProgress; 
 }
 /**
  * Sets the correct position for new package declaration:<ul>
@@ -128,8 +120,8 @@
 	if (!status.isOK()) {
 		return status;
 	}
-	if (JavaConventions.validatePackageName(fName).getSeverity() == IStatus.ERROR) {
-		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, fName);
+	if (JavaConventions.validatePackageName(this.name).getSeverity() == IStatus.ERROR) {
+		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_NAME, this.name);
 	}
 	return JavaModelStatus.VERIFIED_OK;
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java
index e4bdf14..fa757f5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreatePackageFragmentOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,6 +24,7 @@
 import org.eclipse.jdt.core.JavaConventions;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -68,7 +69,7 @@
 protected void executeOperation() throws JavaModelException {
 	JavaElementDelta delta = null;
 	PackageFragmentRoot root = (PackageFragmentRoot) getParentElement();
-	beginTask(Util.bind("operation.createPackageFragmentProgress"), this.pkgName.length); //$NON-NLS-1$
+	beginTask(Messages.operation_createPackageFragmentProgress, this.pkgName.length); 
 	IContainer parentFolder = (IContainer) root.getResource();
 	String[] sideEffectPackageName = CharOperation.NO_STRINGS; 
 	ArrayList results = new ArrayList(this.pkgName.length);
@@ -139,7 +140,7 @@
 			if (subFolder.getType() != IResource.FOLDER) {
 				return new JavaModelStatus(
 					IJavaModelStatusConstants.NAME_COLLISION, 
-					Util.bind("status.nameCollision", subFolder.getFullPath().toString())); //$NON-NLS-1$
+					Messages.bind(Messages.status_nameCollision, subFolder.getFullPath().toString())); 
 			}
 			parentFolder = (IContainer) subFolder;
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java
index 97deaf5..49a9879 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeHierarchyOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -46,9 +46,9 @@
  * given type within the specified region, in the context of
  * the given project.
  */
-public CreateTypeHierarchyOperation(IRegion region, IJavaProject project, ICompilationUnit[] workingCopies, IType element, boolean computeSubtypes) {
+public CreateTypeHierarchyOperation(IRegion region, ICompilationUnit[] workingCopies, IType element, boolean computeSubtypes) {
 	super(element);
-	this.typeHierarchy = new RegionBasedTypeHierarchy(region, project, workingCopies, element, computeSubtypes);
+	this.typeHierarchy = new RegionBasedTypeHierarchy(region, workingCopies, element, computeSubtypes);
 }
 /**
  * Constructs an operation to create a type hierarchy for the
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
index 912aec1..797263b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeMemberOperation.java
@@ -1,24 +1,39 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
-import org.eclipse.jdt.core.IBuffer;
+import java.util.List;
+import java.util.Map;
+
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatus;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
+import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
 import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.dom.rewrite.Indents;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.TextUtilities;
 
 /**
  * Implements functionality common to
@@ -28,71 +43,125 @@
 	/**
 	 * The source code for the new member.
 	 */
-	protected String fSource = null;
+	protected String source = null;
 	/**
-	 * The name of the <code>DOMNode</code> that may be used to
+	 * The name of the <code>ASTNode</code> that may be used to
 	 * create this new element.
 	 * Used by the <code>CopyElementsOperation</code> for renaming
 	 */
-	protected String fAlteredName;
+	protected String alteredName;
 	/**
-	 * The JDOM document fragment representing the element that
+	 * The AST node representing the element that
 	 * this operation created.
-	 * @deprecated JDOM is obsolete
 	 */
-     // TODO - JDOM - remove once model ported off of JDOM
-	 protected IDOMNode fDOMNode;
+	 protected ASTNode createdNode;
 /**
  * When executed, this operation will create a type member
  * in the given parent element with the specified source.
  */
 public CreateTypeMemberOperation(IJavaElement parentElement, String source, boolean force) {
 	super(parentElement);
-	fSource= source;
-	this.force= force;
+	this.source = source;
+	this.force = force;
 }
-/**
- * @see CreateElementInCUOperation#generateNewCompilationUnitDOM
- * @deprecated JDOM is obsolete
+protected StructuralPropertyDescriptor getChildPropertyDescriptor(ASTNode parent) {
+	switch (parent.getNodeType()) {
+		case ASTNode.COMPILATION_UNIT:
+			return CompilationUnit.TYPES_PROPERTY;
+		case ASTNode.ENUM_DECLARATION:
+			return EnumDeclaration.BODY_DECLARATIONS_PROPERTY;
+		case ASTNode.ANNOTATION_TYPE_DECLARATION:
+			return AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY;
+		default:
+			return TypeDeclaration.BODY_DECLARATIONS_PROPERTY;
+	}
+}
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
+	if (this.createdNode == null) {
+		this.source = removeIndentAndNewLines(this.source, document, cu);
+		ASTParser parser = ASTParser.newParser(AST.JLS3);
+		parser.setSource(this.source.toCharArray());
+		parser.setProject(getCompilationUnit().getJavaProject());
+		parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS);
+		ASTNode node = parser.createAST(this.progressMonitor);
+		String createdNodeSource;
+		if (node.getNodeType() != ASTNode.TYPE_DECLARATION) {
+			createdNodeSource = generateSyntaxIncorrectAST();
+			if (this.createdNode == null)
+				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
+		} else {
+			TypeDeclaration typeDeclaration = (TypeDeclaration) node;
+			this.createdNode = (ASTNode) typeDeclaration.bodyDeclarations().iterator().next();
+			createdNodeSource = this.source;
+		}
+		if (this.alteredName != null) {
+			SimpleName newName = this.createdNode.getAST().newSimpleName(this.alteredName);
+			SimpleName oldName = rename(this.createdNode, newName);
+			int nameStart = oldName.getStartPosition();
+			int nameEnd = nameStart + oldName.getLength();
+			StringBuffer newSource = new StringBuffer();
+			if (this.source.equals(createdNodeSource)) {
+				newSource.append(createdNodeSource.substring(0, nameStart));
+				newSource.append(this.alteredName);
+				newSource.append(createdNodeSource.substring(nameEnd));
+			} else {
+				// syntacticaly incorrect source
+				int createdNodeStart = this.createdNode.getStartPosition();
+				int createdNodeEnd = createdNodeStart + this.createdNode.getLength();
+				newSource.append(createdNodeSource.substring(createdNodeStart, nameStart));
+				newSource.append(this.alteredName);
+				newSource.append(createdNodeSource.substring(nameEnd, createdNodeEnd));
+				
+			}
+			this.source = newSource.toString();
+		}
+	}
+	if (rewriter == null) return this.createdNode;
+	// return a string place holder (instead of the created node) so has to not lose comments and formatting
+	return rewriter.createStringPlaceholder(this.source, this.createdNode.getNodeType());
+}
+private String removeIndentAndNewLines(String code, IDocument document, ICompilationUnit cu) {
+	IJavaProject project = cu.getJavaProject();
+	Map options = project.getOptions(true/*inherit JavaCore options*/);
+	int tabWidth = Indents.getTabWidth(options);
+	int indentWidth = Indents.getIndentWidth(options, tabWidth);
+	int indent = Indents.computeIndentUnits(code, tabWidth, indentWidth);
+	int firstNonWhiteSpace = -1;
+	int length = code.length();
+	while (firstNonWhiteSpace < length-1)
+		if (!Character.isWhitespace(code.charAt(++firstNonWhiteSpace)))
+			break;
+	int lastNonWhiteSpace = length;
+	while (lastNonWhiteSpace > 0)
+		if (!Character.isWhitespace(code.charAt(--lastNonWhiteSpace)))
+			break;
+	String lineDelimiter = TextUtilities.getDefaultLineDelimiter(document);
+	return Indents.changeIndent(code.substring(firstNonWhiteSpace, lastNonWhiteSpace+1), indent, tabWidth, indentWidth, "", lineDelimiter); //$NON-NLS-1$
+}
+/*
+ * Renames the given node to the given name.
+ * Returns the old name.
  */
-// TODO - JDOM - remove once model ported off of JDOM
-protected void generateNewCompilationUnitDOM(ICompilationUnit cu) throws JavaModelException {
-	IBuffer buffer = cu.getBuffer();
-	if (buffer == null) return;
-	char[] prevSource = buffer.getCharacters();
-	if (prevSource == null) return;
-
-	// create a JDOM for the compilation unit
-	fCUDOM = (new DOMFactory()).createCompilationUnit(prevSource, cu.getElementName());
-	IDOMNode parent = ((JavaElement) getParentElement()).findNode(fCUDOM);
-	if (parent == null) {
-		//#findNode does not work for autogenerated CUs as the contents are empty
-		parent = fCUDOM;
-	}
-	IDOMNode child = deprecatedGenerateElementDOM();
-	if (child != null) {
-		insertDOMNode(parent, child);
-	}
-	worked(1);
-}
+protected abstract SimpleName rename(ASTNode node, SimpleName newName);
 /**
- * Generates a <code>IDOMNode</code> based on the source of this operation
+ * Generates an <code>ASTNode</code> based on the source of this operation
  * when there is likely a syntax error in the source.
- * @deprecated JDOM is obsolete
+ * Returns the source used to generate this node.
  */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateSyntaxIncorrectDOM() {
-	//create some dummy source to generate a dom node
+protected String generateSyntaxIncorrectAST() {
+	//create some dummy source to generate an ast node
 	StringBuffer buff = new StringBuffer();
 	buff.append(Util.LINE_SEPARATOR + " public class A {" + Util.LINE_SEPARATOR); //$NON-NLS-1$
-	buff.append(fSource);
+	buff.append(this.source);
 	buff.append(Util.LINE_SEPARATOR).append('}');
-	IDOMCompilationUnit domCU = (new DOMFactory()).createCompilationUnit(buff.toString(), "A.java"); //$NON-NLS-1$
-	IDOMNode node = (IDOMNode) domCU.getChild("A").getChildren().nextElement(); //$NON-NLS-1$
-	if (node != null) {
-		node.remove();
-	}
-	return node;
+	ASTParser parser = ASTParser.newParser(AST.JLS3);
+	parser.setSource(buff.toString().toCharArray());
+	CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
+	TypeDeclaration typeDeclaration = (TypeDeclaration) compilationUnit.types().iterator().next();
+	List bodyDeclarations = typeDeclaration.bodyDeclarations();
+	if (bodyDeclarations.size() != 0)
+		this.createdNode = (ASTNode) bodyDeclarations.iterator().next();
+	return buff.toString();
 }
 /**
  * Returns the IType the member is to be created in.
@@ -101,12 +170,12 @@
 	return (IType)getParentElement();
 }
 /**
- * Sets the name of the <code>DOMNode</code> that will be used to
+ * Sets the name of the <code>ASTNode</code> that will be used to
  * create this new element.
  * Used by the <code>CopyElementsOperation</code> for renaming
  */
 protected void setAlteredName(String newName) {
-	fAlteredName = newName;
+	this.alteredName = newName;
 }
 /**
  * Possible failures: <ul>
@@ -121,19 +190,14 @@
 	if (!status.isOK()) {
 		return status;
 	}
-	IJavaElement parent = getParentElement(); // non-null since check was done in supper
-	Member localContext;
-	if (parent instanceof Member && (localContext = ((Member)parent).getOuterMostLocalContext()) != null && localContext != parent) {
-		// JDOM doesn't support source manipulation in local/anonymous types
-		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, parent);
-	}
-	if (fSource == null) {
+	if (this.source == null) {
 		return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS);
 	}
 	if (!force) {
 		//check for name collisions
 		try {
-			deprecatedGenerateElementDOM();
+			ICompilationUnit cu = getCompilationUnit();
+			generateElementAST(null, getDocument(cu), cu);
 		} catch (JavaModelException jme) {
 			return jme.getJavaModelStatus();
 		}
@@ -143,13 +207,6 @@
 	return JavaModelStatus.VERIFIED_OK;
 }
 /**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private IDOMNode deprecatedGenerateElementDOM() throws JavaModelException {
-	return generateElementDOM();
-}
-/**
  * Verify for a name collision in the destination container.
  */
 protected IJavaModelStatus verifyNameCollision() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java
index 80c47c9..79a0831 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateTypeOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,8 +16,12 @@
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * <p>This operation creates a class or interface.
@@ -36,30 +40,13 @@
 public CreateTypeOperation(IJavaElement parentElement, String source, boolean force) {
 	super(parentElement, source, force);
 }
-/**
- * @see CreateElementInCUOperation#generateElementDOM()
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected IDOMNode generateElementDOM() throws JavaModelException {
-	if (fDOMNode == null) {
-		fDOMNode = (new DOMFactory()).createType(fSource);
-		if (fDOMNode == null) {
-			//syntactically incorrect source
-			fDOMNode = generateSyntaxIncorrectDOM();
-			if (fDOMNode == null) {
-				throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-			}
-		}
-		if (fAlteredName != null && fDOMNode != null) {
-			fDOMNode.setName(fAlteredName);
-		}
-	}
-	if (!(fDOMNode instanceof IDOMType)) {
+protected ASTNode generateElementAST(ASTRewrite rewriter, IDocument document, ICompilationUnit cu) throws JavaModelException {
+	ASTNode node = super.generateElementAST(rewriter, document, cu);
+	if (!(node instanceof AbstractTypeDeclaration))
 		throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.INVALID_CONTENTS));
-	}
-	return fDOMNode;
+	return node;
 }
+
 /**
  * @see CreateElementInCUOperation#generateResultHandle()
  */
@@ -67,9 +54,9 @@
 	IJavaElement parent= getParentElement();
 	switch (parent.getElementType()) {
 		case IJavaElement.COMPILATION_UNIT:
-			return ((ICompilationUnit)parent).getType(getDOMNodeName());
+			return ((ICompilationUnit)parent).getType(getASTNodeName());
 		case IJavaElement.TYPE:
-			return ((IType)parent).getType(getDOMNodeName());
+			return ((IType)parent).getType(getASTNodeName());
 		// Note: creating local/anonymous type is not supported 
 	}
 	return null;
@@ -78,7 +65,7 @@
  * @see CreateElementInCUOperation#getMainTaskName()
  */
 public String getMainTaskName(){
-	return Util.bind("operation.createTypeProgress"); //$NON-NLS-1$
+	return Messages.operation_createTypeProgress; 
 }
 /**
  * Returns the <code>IType</code> the member is to be created in.
@@ -97,28 +84,32 @@
 	IJavaElement parent = getParentElement();
 	switch (parent.getElementType()) {
 		case IJavaElement.COMPILATION_UNIT:
-			if (((ICompilationUnit) parent).getType(getDOMNodeName()).exists()) {
+			String typeName = getASTNodeName();
+			if (((ICompilationUnit) parent).getType(typeName).exists()) {
 				return new JavaModelStatus(
 					IJavaModelStatusConstants.NAME_COLLISION, 
-					Util.bind("status.nameCollision", getDOMNodeName())); //$NON-NLS-1$
+					Messages.bind(Messages.status_nameCollision, typeName)); 
 			}
 			break;
 		case IJavaElement.TYPE:
-			if (((IType) parent).getType(getDOMNodeName()).exists()) {
+			typeName = getASTNodeName();
+			if (((IType) parent).getType(typeName).exists()) {
 				return new JavaModelStatus(
 					IJavaModelStatusConstants.NAME_COLLISION, 
-					Util.bind("status.nameCollision", getDOMNodeName())); //$NON-NLS-1$
+					Messages.bind(Messages.status_nameCollision, typeName)); 
 			}
 			break;
 		// Note: creating local/anonymous type is not supported 
 	}
 	return JavaModelStatus.VERIFIED_OK;
 }
-/**
- * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
- */
-// TODO - JDOM - remove once model ported off of JDOM
-private String getDOMNodeName() {
-	return fDOMNode.getName();
+private String getASTNodeName() {
+	return ((AbstractTypeDeclaration) this.createdNode).getName().getIdentifier();
+}
+protected SimpleName rename(ASTNode node, SimpleName newName) {
+	AbstractTypeDeclaration type = (AbstractTypeDeclaration) node;
+	SimpleName oldName = type.getName();
+	type.setName(newName);
+	return oldName;
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java
index 9897465..f9c8872 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DefaultWorkingCopyOwner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java
index 703160a..c4c99a7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteElementsOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,15 +17,20 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.IRegion;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.text.edits.TextEdit;
 
 /**
  * This operation deletes a collection of elements (and
@@ -46,12 +51,10 @@
 	 */ 
 	protected Map childrenToRemove;
 	/**
-	 * The <code>DOMFactory</code> used to manipulate the source code of
-	 * <code>ICompilationUnit</code>s.
-	 * @deprecated JDOM is obsolete 
+	 * The <code>ASTParser</code> used to manipulate the source code of
+	 * <code>ICompilationUnit</code>.
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected DOMFactory factory;
+	protected ASTParser parser;
 	/**
 	 * When executed, this operation will delete the given elements. The elements
 	 * to delete cannot be <code>null</code> or empty, and must be contained within a
@@ -59,22 +62,38 @@
 	 */
 	public DeleteElementsOperation(IJavaElement[] elementsToDelete, boolean force) {
 		super(elementsToDelete, force);
-		initDOMFactory();
+		initASTParser();
 	}
 	
-	/**
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	private void initDOMFactory() {
-		factory = new DOMFactory();
+	private void deleteElement(IJavaElement elementToRemove, ICompilationUnit cu) throws JavaModelException {
+		// ensure cu is consistent (noop if already consistent)
+		cu.makeConsistent(this.progressMonitor);
+		this.parser.setSource(cu);
+		CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
+		ASTNode node = ((JavaElement) elementToRemove).findNode(astCU);
+		if (node == null) 
+			Assert.isTrue(false, "Failed to locate " + elementToRemove.getElementName() + " in " + cu.getElementName()); //$NON-NLS-1$//$NON-NLS-2$
+		IDocument document = getDocument(cu);
+		AST ast = astCU.getAST();
+		ASTRewrite rewriter = ASTRewrite.create(ast);
+		rewriter.remove(node, null);
+ 		TextEdit edits = rewriter.rewriteAST(document, null);
+ 		try {
+	 		edits.apply(document);
+ 		} catch (BadLocationException e) {
+ 			throw new JavaModelException(e, IJavaModelStatusConstants.INVALID_CONTENTS);
+ 		}
+	}
+
+	private void initASTParser() {
+		this.parser = ASTParser.newParser(AST.JLS3);
 	}
 
 	/**
 	 * @see MultiOperation
 	 */
 	protected String getMainTaskName() {
-		return Util.bind("operation.deleteElementProgress"); //$NON-NLS-1$
+		return Messages.operation_deleteElementProgress; 
 	}
 	protected ISchedulingRule getSchedulingRule() {
 		if (this.elementsToProcess != null && this.elementsToProcess.length == 1) {
@@ -126,17 +145,12 @@
 		// the import container (and report it in the delta)
 		int numberOfImports = cu.getImports().length;
 	
-		IBuffer buffer = cu.getBuffer();
-		if (buffer == null) return;
 		JavaElementDelta delta = new JavaElementDelta(cu);
 		IJavaElement[] cuElements = ((IRegion) childrenToRemove.get(cu)).getElements();
 		for (int i = 0, length = cuElements.length; i < length; i++) {
 			IJavaElement e = cuElements[i];
 			if (e.exists()) {
-				char[] contents = buffer.getCharacters();
-				if (contents == null) continue;
-				String cuName = cu.getElementName();
-				replaceElementInBuffer(buffer, e, cuName);
+				deleteElement(e, cu);
 				delta.removed(e);
 				if (e.getElementType() == IJavaElement.IMPORT_DECLARATION) {
 					numberOfImports--;
@@ -155,19 +169,6 @@
 		}
 	}
 	/**
-	 * @deprecated marked deprecated to suppress JDOM-related deprecation warnings
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	private void replaceElementInBuffer(IBuffer buffer, IJavaElement elementToRemove, String cuName) {
-		IDOMCompilationUnit cuDOM = factory.createCompilationUnit(buffer.getCharacters(), cuName);
-		org.eclipse.jdt.internal.core.jdom.DOMNode node = (org.eclipse.jdt.internal.core.jdom.DOMNode)((JavaElement) elementToRemove).findNode(cuDOM);
-		if (node == null) Assert.isTrue(false, "Failed to locate " + elementToRemove.getElementName() + " in " + cuDOM.getName()); //$NON-NLS-1$//$NON-NLS-2$
-
-		int startPosition = node.getStartPosition();
-		buffer.replace(startPosition, node.getEndPosition() - startPosition + 1, CharOperation.NO_CHAR);
-	}
-
-	/**
 	 * @see MultiOperation
 	 * This method first group the elements by <code>ICompilationUnit</code>,
 	 * and then processes the <code>ICompilationUnit</code>.
@@ -186,12 +187,6 @@
 			if (child.getCorrespondingResource() != null)
 				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, child);
 
-			Member localContext;
-			if (child instanceof Member && (localContext = ((Member)child).getOuterMostLocalContext()) != null && localContext != child) {
-				// JDOM doesn't support source manipulation in local/anonymous types
-				error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, child);
-			}
-
 			if (child.isReadOnly())
 				error(IJavaModelStatusConstants.READ_ONLY, child);
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java
index d4f2294..966bd67 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeletePackageFragmentRootOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java
index b4b26cd..b036daf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeleteResourceElementsOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,7 +20,7 @@
 import org.eclipse.jdt.core.IOpenable;
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * This operation deletes a collection of resources and all of their children.
@@ -97,7 +97,7 @@
  * @see MultiOperation
  */
 protected String getMainTaskName() {
-	return Util.bind("operation.deleteResourceProgress"); //$NON-NLS-1$
+	return Messages.operation_deleteResourceProgress; 
 }
 /**
  * @see MultiOperation This method delegate to <code>deleteResource</code> or
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
index a367e3b..678ade5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -240,6 +240,10 @@
 				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=47213
 				if (!this.initializingThreads.add(currentThread)) return;
 				addedCurrentThread = true;
+				
+				// all classpaths in the workspace are going to be resolved
+				// ensure that containers are initialized in one batch
+				JavaModelManager.getJavaModelManager().batchContainerInitializations = true;
 
 				newRoots = new HashMap();
 				newOtherRoots = new HashMap();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index f915e8e..38cbb77 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -178,6 +178,7 @@
 	private final static int NON_JAVA_RESOURCE = -1;
 	public static boolean DEBUG = false;
 	public static boolean VERBOSE = false;
+	public static boolean PERF = false;
 
 	public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with ElementChangedEvent event masks
 
@@ -1423,7 +1424,15 @@
 						Util.log(exception, "Exception occurred in listener of Java element change notification"); //$NON-NLS-1$
 					}
 					public void run() throws Exception {
+						PerformanceStats stats = null;
+						if(PERF) {
+							stats = PerformanceStats.getStats(JavaModelManager.DELTA_LISTENER_PERF, listener);
+							stats.startRun();
+						}
 						listener.elementChanged(extraEvent);
+						if(PERF) {
+							stats.endRun();
+						}
 					}
 				});
 				if (VERBOSE) {
@@ -2369,7 +2378,8 @@
 						indexManager.addBinary(file, binaryFolderPath);
 						break;
 					case IResourceDelta.REMOVED :
-						indexManager.remove(file.getFullPath().toString(), binaryFolderPath);
+						String containerRelativePath = Util.relativePath(file.getFullPath(), binaryFolderPath.segmentCount());
+						indexManager.remove(containerRelativePath, binaryFolderPath);
 						break;
 				}
 				break;
@@ -2385,7 +2395,7 @@
 						indexManager.addSource(file, file.getProject().getFullPath());
 						break;
 					case IResourceDelta.REMOVED :
-						indexManager.remove(file.getFullPath().toString(), file.getProject().getFullPath());
+						indexManager.remove(Util.relativePath(file.getFullPath(), 1/*remove project segment*/), file.getProject().getFullPath());
 						break;
 				}
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java
index 37a2a9a..fc424d6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DiscardWorkingCopyOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DocumentAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DocumentAdapter.java
new file mode 100644
index 0000000..e99e8d6
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DocumentAdapter.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+
+/*
+ * Adapts an IBuffer to IDocument
+ */
+public class DocumentAdapter extends Document {
+	
+	private IBuffer buffer;
+	
+	public DocumentAdapter(IBuffer buffer) {
+		super(buffer.getContents());
+		this.buffer = buffer;
+	}
+
+	public void set(String text) {
+		super.set(text);
+		this.buffer.setContents(text);
+	}
+
+	public void replace(int offset, int length, String text) throws BadLocationException {
+		super.replace(offset, length, text);
+		this.buffer.replace(offset, length, text);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java
index f97c292..a9ce910 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ElementCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java
index f334805..55b467c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IJavaElementRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java
index e7479e1..5c42b88 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/INamingRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java
index ce90eed..c303e6a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/IPathRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
index fe7e9ee..82efebf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -64,7 +64,12 @@
  * @see IImportContainer
  */
 public IImportDeclaration getImport(String importName) {
-	return new ImportDeclaration(this, importName);
+	int index = importName.indexOf(".*"); ///$NON-NLS-1$
+	boolean isOnDemand = index != -1;
+	if (isOnDemand)
+		// make sure to copy the string (so that it doesn't hold on the underlying char[] that might be much bigger than necessary)
+		importName = new String(importName.substring(0, index));
+	return new ImportDeclaration(this, importName, isOnDemand);
 }
 /*
  * @see JavaElement#getPrimaryElement(boolean)
@@ -85,13 +90,6 @@
 	return range;
 }
 /**
- * Import containers only exist if they have children.
- * @see IParent
- */
-public boolean hasChildren() {
-	return true;
-}
-/**
  */
 public String readableName() {
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
index 8b29cc5..3d33bce 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,38 +13,36 @@
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.IImportDeclaration;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
 
 /**
  * Handle for an import declaration. Info object is a ImportDeclarationElementInfo.
  * @see IImportDeclaration
  */
 
-/* package */ class ImportDeclaration extends SourceRefElement implements IImportDeclaration {
+public class ImportDeclaration extends SourceRefElement implements IImportDeclaration {
 
 	protected String name;
+	protected boolean isOnDemand;
 	
 /**
  * Constructs an ImportDeclaration in the given import container
  * with the given name.
  */
-protected ImportDeclaration(ImportContainer parent, String name) {
+protected ImportDeclaration(ImportContainer parent, String name, boolean isOnDemand) {
 	super(parent);
 	this.name = name;
+	this.isOnDemand = isOnDemand;
 }
 public boolean equals(Object o) {
 	if (!(o instanceof ImportDeclaration)) return false;
 	return super.equals(o);
 }
-/**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	return (node.getNodeType() == IDOMNode.IMPORT) && getElementName().equals(node.getName());
-}
 public String getElementName() {
+	if (this.isOnDemand)
+		return this.name + ".*"; //$NON-NLS-1$
+	return this.name;
+}
+public String getNameWithoutStar() {
 	return this.name;
 }
 /**
@@ -86,13 +84,13 @@
 public IJavaElement getPrimaryElement(boolean checkOwner) {
 	CompilationUnit cu = (CompilationUnit)this.parent.getParent();
 	if (checkOwner && cu.isPrimary()) return this;
-	return cu.getImport(this.name);
+	return cu.getImport(getElementName());
 }
 /**
  * Returns true if the import is on-demand (ends with ".*")
  */
 public boolean isOnDemand() {
-	return this.name.endsWith(".*"); //$NON-NLS-1$
+	return this.isOnDemand;
 }
 /**
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java
index 12a5372..2554b08 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportDeclarationElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,22 +18,5 @@
  */
 public class ImportDeclarationElementInfo extends MemberElementInfo implements ISourceImport{
 	
-	char[] name;
-	
-	// record if import is on demand, the import name doesn't have trailing start
-	boolean onDemand;
-	
-	public char[] getName() {
-		return this.name;
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.compiler.env.ISourceImport#onDemand()
-	 */
-	public boolean onDemand() {
-		return this.onDemand;
-	}
-
-	public void setOnDemand(boolean onDemand) {
-		this.onDemand = onDemand;
-	}
+	// empty element info
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
index e0d4e91..de25ee6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Initializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,7 +18,6 @@
 import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -39,22 +38,6 @@
 	return super.equals(o);
 }
 /**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	if (node.getNodeType() == IDOMNode.INITIALIZER) {
-		try {
-			return node.getContents().trim().equals(getSource());
-		} catch (JavaModelException e) {
-			return false;
-		}
-	} else {
-		return false;
-	}
-}
-/**
  * @see IJavaElement
  */
 public int getElementType() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java
index a9be5d6..665aa22 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InitializerElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java
index 79feb1f..3e28798 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/InternalNamingConventions.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
index c1c124c..b457b77 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
index 26cbbe6..3ef3b6a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
index f8dba53..ed4f277 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
index fd2f43b..2aafe2a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java
index 5dd52ea..e353be5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRootInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
index 000cfa5..a13b85a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaCorePreferenceInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -44,6 +44,7 @@
 		defaultOptionsMap.put(JavaCore.COMPILER_TASK_PRIORITIES, JavaCore.DEFAULT_TASK_PRIORITIES);
 		defaultOptionsMap.put(JavaCore.COMPILER_TASK_CASE_SENSITIVE, JavaCore.ENABLED);
 		defaultOptionsMap.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
+		defaultOptionsMap.put(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, JavaCore.ERROR);
 	
 		// Builder settings
 		defaultOptionsMap.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, ""); //$NON-NLS-1$
@@ -63,7 +64,13 @@
 		optionNames.add(JavaCore.CORE_ENCODING);
 
 		// Formatter settings
-		formatterSettings(defaultOptionsMap, optionNames);
+		Map codeFormatterOptionsMap = DefaultCodeFormatterConstants.getEclipseDefaultSettings(); // code formatter defaults
+		for (Iterator iter = codeFormatterOptionsMap.entrySet().iterator(); iter.hasNext();) {
+			Map.Entry entry = (Map.Entry) iter.next();
+			String optionName = (String) entry.getKey();
+			defaultOptionsMap.put(optionName, entry.getValue());
+			optionNames.add(optionName);
+		}
 
 		// CodeAssist settings
 		defaultOptionsMap.put(JavaCore.CODEASSIST_VISIBILITY_CHECK, JavaCore.DISABLED); //$NON-NLS-1$
@@ -76,7 +83,8 @@
 		defaultOptionsMap.put(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, ""); //$NON-NLS-1$
 		defaultOptionsMap.put(JavaCore.CODEASSIST_LOCAL_SUFFIXES, ""); //$NON-NLS-1$
 		defaultOptionsMap.put(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, ""); //$NON-NLS-1$
-		defaultOptionsMap.put(JavaCore.CODEASSIST_RESTRICTIONS_CHECK, JavaCore.DISABLED); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_FORBIDDEN_REFERENCE_CHECK, JavaCore.DISABLED); //$NON-NLS-1$
+		defaultOptionsMap.put(JavaCore.CODEASSIST_DISCOURAGED_REFERENCE_CHECK, JavaCore.DISABLED); //$NON-NLS-1$
 		
 		// Store default values to default preferences
 	 	IEclipsePreferences defaultPreferences = new DefaultScope().getNode(JavaCore.PLUGIN_ID);
@@ -87,28 +95,4 @@
 			optionNames.add(optionName);
 		}
 	}
-	
-	/**
-	 * Avoid depraction warnings on formatter settings
-	 * @deprecated
-	 */
-	private void formatterSettings(Map defaultOptionsMap, HashSet optionNames) {
-		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();
-			defaultOptionsMap.put(optionName, entry.getValue());
-			optionNames.add(optionName);
-		}		
-		defaultOptionsMap.put(JavaCore.FORMATTER_NEWLINE_OPENING_BRACE, JavaCore.DO_NOT_INSERT); 
-		defaultOptionsMap.put(JavaCore.FORMATTER_NEWLINE_CONTROL, JavaCore.DO_NOT_INSERT);
-		defaultOptionsMap.put(JavaCore.FORMATTER_CLEAR_BLANK_LINES, JavaCore.PRESERVE_ONE); 
-		defaultOptionsMap.put(JavaCore.FORMATTER_NEWLINE_ELSE_IF, JavaCore.DO_NOT_INSERT);
-		defaultOptionsMap.put(JavaCore.FORMATTER_NEWLINE_EMPTY_BLOCK, JavaCore.INSERT); 
-		defaultOptionsMap.put(JavaCore.FORMATTER_LINE_SPLIT, "80"); //$NON-NLS-1$
-		defaultOptionsMap.put(JavaCore.FORMATTER_COMPACT_ASSIGNMENT, JavaCore.NORMAL); 
-		defaultOptionsMap.put(JavaCore.FORMATTER_TAB_CHAR, JavaCore.TAB); 
-		defaultOptionsMap.put(JavaCore.FORMATTER_TAB_SIZE, "4"); //$NON-NLS-1$ 
-		defaultOptionsMap.put(JavaCore.FORMATTER_SPACE_CASTEXPRESSION, JavaCore.INSERT); //$NON-NLS-1$ 
-	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
index ee45232..5a5a4f8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,7 +17,9 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
 import org.eclipse.jdt.internal.core.util.Util;
 
@@ -103,15 +105,6 @@
 		return getElementName().equals(other.getElementName()) &&
 				this.parent.equals(other.parent);
 	}
-	/**
-	 * Returns true if this <code>JavaElement</code> is equivalent to the given
-	 * <code>IDOMNode</code>.
-	 * @deprecated JDOM is obsolete
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected boolean equalsDOMNode(IDOMNode node) {
-		return false;
-	}
 	protected void escapeMementoName(StringBuffer buffer, String mementoName) {
 		for (int i = 0, length = mementoName.length(); i < length; i++) {
 			char character = mementoName.charAt(i);
@@ -150,63 +143,11 @@
 	}
 	
 	/**
-	 * Returns the <code>IDOMNode</code> that corresponds to this <code>JavaElement</code>
+	 * Returns the <code>ASTNode</code> that corresponds to this <code>JavaElement</code>
 	 * or <code>null</code> if there is no corresponding node.
-	 * @deprecated JDOM is obsolete
 	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	public IDOMNode findNode(IDOMCompilationUnit dom) {
-		int type = getElementType();
-		if (type == IJavaElement.COMPILATION_UNIT || 
-			type == IJavaElement.FIELD || 
-			type == IJavaElement.IMPORT_DECLARATION || 
-			type == IJavaElement.INITIALIZER || 
-			type == IJavaElement.METHOD || 
-			type == IJavaElement.PACKAGE_DECLARATION || 
-			type == IJavaElement.TYPE) {
-			ArrayList path = new ArrayList();
-			IJavaElement element = this;
-			while (element != null && element.getElementType() != IJavaElement.COMPILATION_UNIT) {
-				if (element.getElementType() != IJavaElement.IMPORT_CONTAINER) {
-					// the DOM does not have import containers, so skip them
-					path.add(0, element);
-				}
-				element = element.getParent();
-			}
-			if (path.size() == 0) {
-				if (equalsDOMNode(dom)) {
-					return dom;
-				} else {
-					return null;
-				}
-			}
-			return ((JavaElement) path.get(0)).followPath(path, 0, dom.getFirstChild());
-		} else {
-			return null;
-		}
-	}
-	/**
-	 * @deprecated JDOM is obsolete
-	 */
-    // TODO - JDOM - remove once model ported off of JDOM
-	protected IDOMNode followPath(ArrayList path, int position, IDOMNode node) {
-	
-		if (equalsDOMNode(node)) {
-			if (position == (path.size() - 1)) {
-				return node;
-			} else {
-				if (node.getFirstChild() != null) {
-					position++;
-					return ((JavaElement)path.get(position)).followPath(path, position, node.getFirstChild());
-				} else {
-					return null;
-				}
-			}
-		} else if (node.getNextNode() != null) {
-			return followPath(path, position, node.getNextNode());
-		} else {
-			return null;
-		}
+	public ASTNode findNode(CompilationUnit ast) {
+		return null; // works only inside a compilation unit
 	}
 	/**
 	 * Generates the element infos for this element, its ancestors (if they are not opened) and its children (if it is an Openable).
@@ -572,6 +513,9 @@
 	public String readableName() {
 		return this.getElementName();
 	}
+	public JavaElement resolved(Binding binding) {
+		return this;
+	}
 	protected String tabString(int tab) {
 		StringBuffer buffer = new StringBuffer();
 		for (int i = tab; i > 0; i--)
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
index 76dc45c..401810c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java
index a758050..afe4ea1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java
index 38a4fda..f45a060 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java
index e316b45..ddcd8d2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
index d64ce12..b3855da 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -31,7 +31,7 @@
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * Implementation of <code>IJavaModel<code>. The Java Model maintains a cache of
@@ -212,7 +212,7 @@
 		case IResource.PROJECT:
 			return new JavaProject((IProject)resource, this);
 		default:
-			throw new IllegalArgumentException(Util.bind("element.invalidResourceForProject")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.element_invalidResourceForProject); 
 	}
 }
 /**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java
index 1576469..4a96fd3 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelCache.java
@@ -1,17 +1,16 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 import java.text.NumberFormat;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 
 import org.eclipse.jdt.core.IJavaElement;
@@ -65,59 +64,6 @@
 	this.childrenCache = new HashMap(DEFAULT_CHILDREN_SIZE);
 }
 
-/*
- * Ensures there is enough room in each ElementCache to put the given new elements.
- */
-protected void ensureSpaceLimit(Map newElements) {
-	int rootSize = 0;
-	IJavaElement project = null;
-	int pkgSize = 0;
-	IJavaElement root = null;
-	int openableSize = 0;
-	IJavaElement pkg = null;
-	Iterator iterator = newElements.keySet().iterator();
-	while (iterator.hasNext()) {
-		IJavaElement element = (IJavaElement) iterator.next();
-		switch (element.getElementType()) {
-			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
-				project = element.getParent();
-				rootSize++;
-				break;
-			case IJavaElement.PACKAGE_FRAGMENT:
-				root = element.getParent();
-				pkgSize++;
-				break;
-			case IJavaElement.COMPILATION_UNIT:
-			case IJavaElement.CLASS_FILE:
-				pkg = element.getParent();
-				openableSize++;
-				break;
-		}
-	}
-	this.rootCache.ensureSpaceLimit(rootSize, project);
-	this.pkgCache.ensureSpaceLimit(pkgSize, root);
-	this.openableCache.ensureSpaceLimit(openableSize, pkg);
-}
-
-/*
- * The given element is being removed.
- * Ensures that the corresponding children cache's space limit is reset if this was the parent
- * that increased the space limit.
- */
-protected void resetSpaceLimit(IJavaElement element) {
-	switch (element.getElementType()) {
-		case IJavaElement.JAVA_PROJECT:
-			this.rootCache.resetSpaceLimit(DEFAULT_ROOT_SIZE, element);
-			break;
-		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
-			this.pkgCache.resetSpaceLimit(DEFAULT_PKG_SIZE, element);
-			break;
-		case IJavaElement.PACKAGE_FRAGMENT:
-			this.openableCache.resetSpaceLimit(DEFAULT_OPENABLE_SIZE, element);
-			break;
-	}
-}
-		
 /**
  *  Returns the info for the element.
  */
@@ -171,12 +117,15 @@
 			break;
 		case IJavaElement.JAVA_PROJECT:
 			this.projectCache.put(element, info);
+			this.rootCache.ensureSpaceLimit(((JavaElementInfo) info).children.length, element);
 			break;
 		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
 			this.rootCache.put(element, info);
+			this.pkgCache.ensureSpaceLimit(((JavaElementInfo) info).children.length, element);
 			break;
 		case IJavaElement.PACKAGE_FRAGMENT:
 			this.pkgCache.put(element, info);
+			this.openableCache.ensureSpaceLimit(((JavaElementInfo) info).children.length, element);
 			break;
 		case IJavaElement.COMPILATION_UNIT:
 		case IJavaElement.CLASS_FILE:
@@ -196,12 +145,15 @@
 			break;
 		case IJavaElement.JAVA_PROJECT:
 			this.projectCache.remove(element);
+			this.rootCache.resetSpaceLimit(DEFAULT_ROOT_SIZE, element);
 			break;
 		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
 			this.rootCache.remove(element);
+			this.pkgCache.resetSpaceLimit(DEFAULT_PKG_SIZE, element);
 			break;
 		case IJavaElement.PACKAGE_FRAGMENT:
 			this.pkgCache.remove(element);
+			this.openableCache.resetSpaceLimit(DEFAULT_OPENABLE_SIZE, element);
 			break;
 		case IJavaElement.COMPILATION_UNIT:
 		case IJavaElement.CLASS_FILE:
@@ -218,15 +170,21 @@
 	buffer.append(this.projectCache.size());
 	buffer.append(" projects\n"); //$NON-NLS-1$
 	buffer.append(prefix);
-	buffer.append("Root cache: "); //$NON-NLS-1$
+	buffer.append("Root cache["); //$NON-NLS-1$
+	buffer.append(this.rootCache.getSpaceLimit());
+	buffer.append("]: "); //$NON-NLS-1$
 	buffer.append(NumberFormat.getInstance().format(this.rootCache.fillingRatio()));
 	buffer.append("%\n"); //$NON-NLS-1$
 	buffer.append(prefix);
-	buffer.append("Package cache: "); //$NON-NLS-1$
+	buffer.append("Package cache["); //$NON-NLS-1$
+	buffer.append(this.pkgCache.getSpaceLimit());
+	buffer.append("]: "); //$NON-NLS-1$
 	buffer.append(NumberFormat.getInstance().format(this.pkgCache.fillingRatio()));
 	buffer.append("%\n"); //$NON-NLS-1$
 	buffer.append(prefix);
-	buffer.append("Openable cache: "); //$NON-NLS-1$
+	buffer.append("Openable cache["); //$NON-NLS-1$
+	buffer.append(this.openableCache.getSpaceLimit());
+	buffer.append("]: "); //$NON-NLS-1$
 	buffer.append(NumberFormat.getInstance().format(this.openableCache.fillingRatio()));
 	buffer.append("%\n"); //$NON-NLS-1$
 	return buffer.toString();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java
index ba479f4..2451d41 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index d278e17..0e9c077 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,7 +20,9 @@
 
 import org.eclipse.core.resources.*;
 import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.preferences.DefaultScope;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.IProblem;
@@ -28,12 +30,14 @@
 import org.eclipse.jdt.internal.codeassist.SelectionEngine;
 import org.eclipse.jdt.internal.compiler.Compiler;
 import org.eclipse.jdt.internal.compiler.util.WeakHashSet;
+import org.eclipse.jdt.internal.compiler.util.WeakHashSetOfCharArray;
 import org.eclipse.jdt.internal.core.builder.JavaBuilder;
 import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
 import org.eclipse.jdt.internal.core.search.AbstractSearchScope;
-import org.eclipse.jdt.internal.core.search.SearchBasicEngine;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
 import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 import org.osgi.service.prefs.BackingStoreException;
 import org.w3c.dom.Element;
@@ -70,7 +74,7 @@
 	public HashMap containers = new HashMap(5);
 	public HashMap previousSessionContainers = new HashMap(5);
 	private ThreadLocal containerInitializationInProgress = new ThreadLocal();
-	public boolean batchContainerInitializations = true;
+	public boolean batchContainerInitializations = false;
 	
 	/*
 	 * A HashSet that contains the IJavaProject whose classpath is being resolved.
@@ -78,10 +82,11 @@
 	private ThreadLocal classpathsBeingResolved = new ThreadLocal();
 	
 	/*
-	 * A pool of symbols used in the Java model.
+	 * Pools of symbols used in the Java model.
 	 * Used as a replacement for String#intern() that could prevent garbage collection of strings on some VMs.
 	 */
-	private WeakHashSet symbols = new WeakHashSet(5);
+	private WeakHashSet stringSymbols = new WeakHashSet(5);
+	private WeakHashSetOfCharArray charArraySymbols = new WeakHashSetOfCharArray(5);
 
 	public final static String CP_VARIABLE_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathVariable."; //$NON-NLS-1$
 	public final static String CP_CONTAINER_PREFERENCES_PREFIX = JavaCore.PLUGIN_ID+".classpathContainer."; //$NON-NLS-1$
@@ -103,6 +108,11 @@
 	public static final String FORMATTER_EXTPOINT_ID = "codeFormatter" ; //$NON-NLS-1$
 	
 	/**
+	 * Value of the content-type for Java source files
+	 */
+	public static final String JAVA_SOURCE_CONTENT_TYPE = JavaCore.PLUGIN_ID+".javaSource" ; //$NON-NLS-1$
+
+	/**
 	 * Special value used for recognizing ongoing initialization and breaking initialization cycles
 	 */
 	public final static IPath VARIABLE_INITIALIZATION_IN_PROGRESS = new Path("Variable Initialization In Progress"); //$NON-NLS-1$
@@ -130,9 +140,23 @@
 	private static final String SELECTION_DEBUG = JavaCore.PLUGIN_ID + "/debug/selection" ; //$NON-NLS-1$
 	private static final String SEARCH_DEBUG = JavaCore.PLUGIN_ID + "/debug/search" ; //$NON-NLS-1$
 
+	public static final String COMPLETION_PERF = JavaCore.PLUGIN_ID + "/perf/completion" ; //$NON-NLS-1$
+	public static final String SELECTION_PERF = JavaCore.PLUGIN_ID + "/perf/selection" ; //$NON-NLS-1$
+	public static final String DELTA_LISTENER_PERF = JavaCore.PLUGIN_ID + "/perf/javadeltalistener" ; //$NON-NLS-1$
+	public static final String VARIABLE_INITIALIZER_PERF = JavaCore.PLUGIN_ID + "/perf/variableinitializer" ; //$NON-NLS-1$
+	public static final String CONTAINER_INITIALIZER_PERF = JavaCore.PLUGIN_ID + "/perf/containerinitializer" ; //$NON-NLS-1$
+	public static final String RECONCILE_PERF = JavaCore.PLUGIN_ID + "/perf/reconcile" ; //$NON-NLS-1$
+	
+	public static boolean PERF_VARIABLE_INITIALIZER = false;
+	public static boolean PERF_CONTAINER_INITIALIZER = false;
+	
 	public final static ICompilationUnit[] NO_WORKING_COPY = new ICompilationUnit[0];
 	
+	// Preferences
 	public HashSet optionNames = new HashSet(20);
+	public final IEclipsePreferences[] preferencesLookup = new IEclipsePreferences[2];
+	static final int PREF_INSTANCE = 0;
+	static final int PREF_DEFAULT = 1;
 
 	/**
 	 * Returns whether the given full path (for a package) conflicts with the output location
@@ -246,6 +270,94 @@
 		// container values are persisted in preferences during save operations, see #saving(ISaveContext)
 	}
 	
+	/*
+	 * Optimize startup case where a container for 1 project is initialized at a time with the same entries as on shutdown.
+	 */
+	public boolean containerPutIfInitializingWithSameEntries(IPath containerPath, IJavaProject[] projects, IClasspathContainer[] respectiveContainers) {
+		int projectLength = projects.length;
+		if (projectLength != 1) 
+			return false;
+		final IClasspathContainer container = respectiveContainers[0];
+		if (container == null)
+			return false;
+		IJavaProject project = projects[0];
+		if (!containerInitializationInProgress(project).contains(containerPath))
+			return false;
+		IClasspathContainer previousSessionContainer = getPreviousSessionContainer(containerPath, project);
+		final IClasspathEntry[] newEntries = container.getClasspathEntries();
+		if (previousSessionContainer == null) 
+			if (newEntries.length == 0) {
+				containerPut(project, containerPath, container);
+				return true;
+			} else {
+				return false;
+			}
+		final IClasspathEntry[] oldEntries = previousSessionContainer.getClasspathEntries();
+		if (oldEntries.length != newEntries.length) 
+			return false;
+		for (int i = 0, length = newEntries.length; i < length; i++) {
+			if (!newEntries[i].equals(oldEntries[i])) {
+				if (CP_RESOLVE_VERBOSE) {
+					Util.verbose(
+						"CPContainer SET  - missbehaving container\n" + //$NON-NLS-1$
+						"	container path: " + containerPath + '\n' + //$NON-NLS-1$
+						"	projects: {" +//$NON-NLS-1$
+						org.eclipse.jdt.internal.compiler.util.Util.toString(
+							projects, 
+							new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){ 
+								public String displayString(Object o) { return ((IJavaProject) o).getElementName(); }
+							}) +
+						"}\n	values on previous session: {\n"  +//$NON-NLS-1$
+						org.eclipse.jdt.internal.compiler.util.Util.toString(
+							respectiveContainers, 
+							new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){ 
+								public String displayString(Object o) { 
+									StringBuffer buffer = new StringBuffer("		"); //$NON-NLS-1$
+									if (o == null) {
+										buffer.append("<null>"); //$NON-NLS-1$
+										return buffer.toString();
+									}
+									buffer.append(container.getDescription());
+									buffer.append(" {\n"); //$NON-NLS-1$
+									for (int j = 0; j < oldEntries.length; j++){
+										buffer.append(" 			"); //$NON-NLS-1$
+										buffer.append(oldEntries[j]); 
+										buffer.append('\n'); 
+									}
+									buffer.append(" 		}"); //$NON-NLS-1$
+									return buffer.toString();
+								}
+							}) +
+						"}\n	new values: {\n"  +//$NON-NLS-1$
+						org.eclipse.jdt.internal.compiler.util.Util.toString(
+							respectiveContainers, 
+							new org.eclipse.jdt.internal.compiler.util.Util.Displayable(){ 
+								public String displayString(Object o) { 
+									StringBuffer buffer = new StringBuffer("		"); //$NON-NLS-1$
+									if (o == null) {
+										buffer.append("<null>"); //$NON-NLS-1$
+										return buffer.toString();
+									}
+									buffer.append(container.getDescription());
+									buffer.append(" {\n"); //$NON-NLS-1$
+									for (int j = 0; j < newEntries.length; j++){
+										buffer.append(" 			"); //$NON-NLS-1$
+										buffer.append(newEntries[j]); 
+										buffer.append('\n'); 
+									}
+									buffer.append(" 		}"); //$NON-NLS-1$
+									return buffer.toString();
+								}
+							}) +
+						"\n	}"); //$NON-NLS-1$
+				}
+				return false;
+			}
+		}
+		containerPut(project, containerPath, container);
+		return true;
+	}
+	
 	private synchronized void containersReset(String[] containerIDs) {
 		for (int i = 0; i < containerIDs.length; i++) {
 			String containerID = containerIDs[i];
@@ -480,7 +592,7 @@
 							pkgPath = pkgPath.removeLastSegments(1);
 						}
 						String[] pkgName = pkgPath.segments();
-						if (pkgName == null || JavaConventions.validatePackageName(Util.packageName(pkgPath)).getSeverity() == IStatus.ERROR) {
+						if (pkgName.length != 0 && JavaConventions.validatePackageName(Util.packageName(pkgPath)).getSeverity() == IStatus.ERROR) {
 							return null;
 						}
 						return root.getPackageFragment(pkgName);
@@ -501,7 +613,7 @@
 	/**
 	 * Infos cache.
 	 */
-	protected JavaModelCache cache = new JavaModelCache();
+	public JavaModelCache cache = new JavaModelCache();
 	
 	/*
 	 * Temporary cache of newly opened elements
@@ -548,6 +660,7 @@
 		public IPath outputLocation;
 		
 		public IEclipsePreferences preferences;
+		public Hashtable options;
 		
 		public PerProjectInfo(IProject project) {
 
@@ -743,7 +856,7 @@
 			if(option != null) NameLookup.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
 
 			option = Platform.getDebugOption(SEARCH_DEBUG);
-			if(option != null) SearchBasicEngine.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
+			if(option != null) BasicSearchEngine.VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
 
 			option = Platform.getDebugOption(SELECTION_DEBUG);
 			if(option != null) SelectionEngine.DEBUG = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
@@ -751,6 +864,16 @@
 			option = Platform.getDebugOption(ZIP_ACCESS_DEBUG);
 			if(option != null) JavaModelManager.ZIP_ACCESS_VERBOSE = option.equalsIgnoreCase("true") ; //$NON-NLS-1$
 		}
+		
+		// configure performance options
+		if(PerformanceStats.ENABLED) {
+			CompletionEngine.PERF = PerformanceStats.isEnabled(COMPLETION_PERF);
+			SelectionEngine.PERF = PerformanceStats.isEnabled(SELECTION_PERF);
+			DeltaProcessor.PERF = PerformanceStats.isEnabled(DELTA_LISTENER_PERF);
+			JavaModelManager.PERF_VARIABLE_INITIALIZER = PerformanceStats.isEnabled(VARIABLE_INITIALIZER_PERF);
+			JavaModelManager.PERF_CONTAINER_INITIALIZER = PerformanceStats.isEnabled(CONTAINER_INITIALIZER_PERF);
+			ReconcileWorkingCopyOperation.PERF = PerformanceStats.isEnabled(RECONCILE_PERF);
+		}
 	}
 	
 	/*
@@ -880,6 +1003,20 @@
 	}
 
 	/**
+	 * Get workpsace eclipse preference for JavaCore plugin.
+	 */
+	public IEclipsePreferences getInstancePreferences() {
+		return preferencesLookup[PREF_INSTANCE];
+	}
+ 
+	/**
+	 * Get default eclipse preference for JavaCore plugin.
+	 */
+	public IEclipsePreferences getDefaultPreferences() {
+		return preferencesLookup[PREF_DEFAULT];
+	}
+
+	/**
 	 * Returns the handle to the active Java Model.
 	 */
 	public final JavaModel getJavaModel() {
@@ -906,7 +1043,7 @@
 			info.triedRead = true;
 			try {
 				if (monitor != null)
-					monitor.subTask(Util.bind("build.readStateProgress", project.getName())); //$NON-NLS-1$
+					monitor.subTask(Messages.bind(Messages.build_readStateProgress, project.getName())); 
 				info.savedState = readState(project);
 			} catch (CoreException e) {
 				e.printStackTrace();
@@ -1146,7 +1283,7 @@
 			// internal resource
 			IPath location;
 			if (file.getType() != IResource.FILE || (location = file.getLocation()) == null) {
-				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("file.notFound", path.toString()), null)); //$NON-NLS-1$
+				throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.bind(Messages.file_notFound, path.toString()), null)); 
 			}
 			fileSystemPath= location.toOSString();
 		} else {
@@ -1164,7 +1301,7 @@
 			}
 			return zipFile;
 		} catch (IOException e) {
-			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Util.bind("status.IOException"), e)); //$NON-NLS-1$
+			throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, -1, Messages.status_IOException, e)); 
 		}
 	}
 	
@@ -1266,6 +1403,11 @@
 					"	invocation stack trace:"); //$NON-NLS-1$
 				new Exception("<Fake exception>").printStackTrace(System.out); //$NON-NLS-1$
 			}
+			PerformanceStats stats = null;
+			if(JavaModelManager.PERF_CONTAINER_INITIALIZER) {
+				stats = PerformanceStats.getStats(JavaModelManager.CONTAINER_INITIALIZER_PERF, this);
+				stats.startRun(containerPath + " of " + project.getPath()); //$NON-NLS-1$
+			}
 			containerPut(project, containerPath, CONTAINER_INITIALIZATION_IN_PROGRESS); // avoid initialization cycles
 			boolean ok = false;
 			try {
@@ -1294,6 +1436,9 @@
 				}
 				throw e;
 			} finally {
+				if(JavaModelManager.PERF_CONTAINER_INITIALIZER) {
+					stats.endRun();
+				}
 				if (!ok) {
 					containerPut(project, containerPath, null); // flush cache
 					if (CP_RESOLVE_VERBOSE) {
@@ -1343,9 +1488,52 @@
 		}
 		return container;
 	}
+
+	/**
+	 * Initialize preferences lookups for JavaCore plugin.
+	 */
+	public void initializePreferences() {
+		
+		// Create lookups
+		preferencesLookup[PREF_INSTANCE] = new InstanceScope().getNode(JavaCore.PLUGIN_ID);
+		preferencesLookup[PREF_DEFAULT] = new DefaultScope().getNode(JavaCore.PLUGIN_ID);
+
+		// Listen to instance preferences node removal from parent in order to refresh stored one
+		IEclipsePreferences.INodeChangeListener listener = new IEclipsePreferences.INodeChangeListener() {
+			public void added(IEclipsePreferences.NodeChangeEvent event) {
+				// do nothing
+			}
+			public void removed(IEclipsePreferences.NodeChangeEvent event) {
+				if (event.getChild() == preferencesLookup[PREF_INSTANCE]) {
+					preferencesLookup[PREF_INSTANCE] = new InstanceScope().getNode(JavaCore.PLUGIN_ID);
+					preferencesLookup[PREF_INSTANCE].addPreferenceChangeListener(new EclipsePreferencesListener());
+				}
+			}
+		};
+		((IEclipsePreferences) preferencesLookup[PREF_INSTANCE].parent()).addNodeChangeListener(listener);
+		preferencesLookup[PREF_INSTANCE].addPreferenceChangeListener(new EclipsePreferencesListener());
+
+		// Listen to default preferences node removal from parent in order to refresh stored one
+		listener = new IEclipsePreferences.INodeChangeListener() {
+			public void added(IEclipsePreferences.NodeChangeEvent event) {
+				// do nothing
+			}
+			public void removed(IEclipsePreferences.NodeChangeEvent event) {
+				if (event.getChild() == preferencesLookup[PREF_DEFAULT]) {
+					preferencesLookup[PREF_DEFAULT] = new DefaultScope().getNode(JavaCore.PLUGIN_ID);
+				}
+			}
+		};
+		((IEclipsePreferences) preferencesLookup[PREF_DEFAULT].parent()).addNodeChangeListener(listener);
+	}
+
+	public synchronized char[] intern(char[] array) {
+		return this.charArraySymbols.add(array);
+	}
 	
 	public synchronized String intern(String s) {
-		return (String) this.symbols.add(s);
+		// make sure to copy the string (so that it doesn't hold on the underlying char[] that might be much bigger than necessary)
+		return (String) this.stringSymbols.add(new String(s));
 		
 		// Note1: String#intern() cannot be used as on some VMs this prevents the string from being garbage collected
 		// Note 2: Instead of using a WeakHashset, one could use a WeakHashMap with the following implementation
@@ -1432,7 +1620,7 @@
 		}
 		
 		// load variables and containers from preferences into cache
-		IEclipsePreferences preferences = JavaCore.getInstancePreferences();
+		IEclipsePreferences preferences = getInstancePreferences();
 
 		// only get variable from preferences not set to their default
 		try {
@@ -1511,9 +1699,6 @@
 			}
 		}
 		
-		// ensure that the elements that are being added have enough room
-		this.cache.ensureSpaceLimit(newElements);
-		
 		Iterator iterator = newElements.keySet().iterator();
 		while (iterator.hasNext()) {
 			IJavaElement element = (IJavaElement)iterator.next();
@@ -1533,10 +1718,10 @@
 				try {
 					String pluginID= in.readUTF();
 					if (!pluginID.equals(JavaCore.PLUGIN_ID))
-						throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$
+						throw new IOException(Messages.build_wrongFileFormat); 
 					String kind= in.readUTF();
 					if (!kind.equals("STATE")) //$NON-NLS-1$
-						throw new IOException(Util.bind("build.wrongFileFormat")); //$NON-NLS-1$
+						throw new IOException(Messages.build_wrongFileFormat); 
 					if (in.readBoolean())
 						return JavaBuilder.readState(project, in);
 					if (JavaBuilder.DEBUG)
@@ -1559,6 +1744,7 @@
 		if (index > 0) {
 			final String projectName = propertyName.substring(containerPrefixLength, index).trim();
 			JavaProject project = (JavaProject)getJavaModelManager().getJavaModel().getJavaProject(projectName);
+			if (!project.getProject().isAccessible()) return; // avoid leaking deleted project's persisted container
 			final IPath containerPath = new Path(propertyName.substring(index+1).trim());
 			
 			if (containerString == null || containerString.equals(CP_ENTRY_IGNORE)) {
@@ -1651,7 +1837,6 @@
 					}
 				}
 				this.cache.removeInfo(element);
-				this.cache.resetSpaceLimit(element);
 				if (wasVerbose) {
 					System.out.println(this.cache.toStringFillingRation("-> ")); //$NON-NLS-1$
 				}
@@ -1674,6 +1859,19 @@
 	}
 
 	/*
+	 * Reset project options stored in info cache.
+	 */
+	public void resetProjectOptions(JavaProject javaProject) {
+		synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock
+			IProject project = javaProject.getProject();
+			PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project);
+			if (info != null) {
+				info.options = null;
+			}
+		}
+	}
+
+	/*
 	 * Reset project preferences stored in info cache.
 	 */
 	public void resetProjectPreferences(JavaProject javaProject) {
@@ -1714,7 +1912,7 @@
 	 */
 	private void saveBuiltState(PerProjectInfo info) throws CoreException {
 		if (JavaBuilder.DEBUG)
-			System.out.println(Util.bind("build.saveStateProgress", info.project.getName())); //$NON-NLS-1$
+			System.out.println(Messages.bind(Messages.build_saveStateProgress, info.project.getName())); 
 		File file = getSerializationFile(info.project);
 		if (file == null) return;
 		long t = System.currentTimeMillis();
@@ -1740,7 +1938,7 @@
 			}
 			throw new CoreException(
 				new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
-					Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+					Messages.bind(Messages.build_cannotSaveState, info.project.getName()), e)); 
 		} catch (IOException e) {
 			try {
 				file.delete();
@@ -1749,11 +1947,11 @@
 			}
 			throw new CoreException(
 				new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, Platform.PLUGIN_ERROR,
-					Util.bind("build.cannotSaveState", info.project.getName()), e)); //$NON-NLS-1$
+					Messages.bind(Messages.build_cannotSaveState, info.project.getName()), e)); 
 		}
 		if (JavaBuilder.DEBUG) {
 			t = System.currentTimeMillis() - t;
-			System.out.println(Util.bind("build.saveStateComplete", String.valueOf(t))); //$NON-NLS-1$
+			System.out.println(Messages.bind(Messages.build_saveStateComplete, String.valueOf(t))); 
 		}
 	}
 
@@ -1764,6 +1962,7 @@
 		
 	    // save container values on snapshot/full save
 		IJavaProject[] projects = getJavaModel().getJavaProjects();
+		IEclipsePreferences preferences = getInstancePreferences();
 		for (int i = 0, length = projects.length; i < length; i++) {
 		    IJavaProject project = projects[i];
 			// clone while iterating (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59638)
@@ -1776,24 +1975,24 @@
 				String containerString = CP_ENTRY_IGNORE;
 				try {
 					if (container != null) {
+						IClasspathEntry[] entries = container.getClasspathEntries();
 						containerString = ((JavaProject)project).encodeClasspath(
-								container.getClasspathEntries(), 
+								entries, 
 								null, 
 								false);
 					}
 				} catch(JavaModelException e){
 					// could not encode entry: leave it as CP_ENTRY_IGNORE
+					Util.log(e, "Could not persist container " + containerPath + " for project " + project.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
 				}
-				JavaCore.getDefaultPreferences().put(containerKey, CP_ENTRY_IGNORE); // TODO (frederic) verify if this is really necessary...
-				JavaCore.getInstancePreferences().put(containerKey, containerString);
+				preferences.put(containerKey, containerString);
 			}
 		}
 		try {
-			JavaCore.getInstancePreferences().flush();
+			preferences.flush();
 		} catch (BackingStoreException e) {
-			// TODO (frederic) see if it's necessary to report this exception
-			// IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving context", e); //$NON-NLS-1$
-			// throw new CoreException(status);
+			IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving context", e); //$NON-NLS-1$
+			throw new CoreException(status);
 		}
 		
 		if (context.getKind() == ISaveContext.FULL_SAVE) {
@@ -1830,7 +2029,7 @@
 		if (vStats != null) {
 			IStatus[] stats= new IStatus[vStats.size()];
 			vStats.toArray(stats);
-			throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR, stats, Util.bind("build.cannotSaveStates"), null)); //$NON-NLS-1$
+			throw new CoreException(new MultiStatus(JavaCore.PLUGIN_ID, IStatus.ERROR, stats, Messages.build_cannotSaveStates, null)); 
 		}
 	}
 
@@ -1942,6 +2141,9 @@
 				"	variables: " + org.eclipse.jdt.internal.compiler.util.Util.toString(variableNames) + '\n' +//$NON-NLS-1$
 				"	values: " + org.eclipse.jdt.internal.compiler.util.Util.toString(variablePaths)); //$NON-NLS-1$
 		}
+		
+		if (variablePutIfInitializingWithSameValue(variableNames, variablePaths))
+			return;
 
 		int varLength = variableNames.length;
 		
@@ -2053,7 +2255,7 @@
 								affectedProject
 									.setRawClasspath(
 										affectedProject.getRawClasspath(),
-										SetClasspathOperation.REUSE_PATH,
+										SetClasspathOperation.DO_NOT_SET_OUTPUT,
 										null, // don't call beginTask on the monitor (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=3717)
 										canChangeResources, 
 										(IClasspathEntry[]) affectedProjectClasspaths.get(affectedProject),
@@ -2128,14 +2330,28 @@
 
 		String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
 		String variableString = variablePath == null ? CP_ENTRY_IGNORE : variablePath.toString();
-		JavaCore.getDefaultPreferences().put(variableKey, CP_ENTRY_IGNORE); // TODO (frederic) verify if this is really necessary...
-		JavaCore.getInstancePreferences().put(variableKey, variableString);
+		getInstancePreferences().put(variableKey, variableString);
 		try {
-			JavaCore.getInstancePreferences().flush();
+			getInstancePreferences().flush();
 		} catch (BackingStoreException e) {
-			// TODO (frederic) see if it's necessary to report this exception
-//			IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, "Problems while saving context", e); //$NON-NLS-1$
-//			throw new CoreException(status);
+			// ignore exception
 		}
 	}
+	
+	/*
+	 * Optimize startup case where 1 variable is initialized at a time with the same value as on shutdown.
+	 */
+	public boolean variablePutIfInitializingWithSameValue(String[] variableNames, IPath[] variablePaths) {
+		if (variableNames.length != 1)
+			return false;
+		String variableName = variableNames[0];
+		IPath oldPath = getPreviousSessionVariable(variableName);
+		if (oldPath == null)
+			return false;
+		IPath newPath = variablePaths[0];
+		if (!oldPath.equals(newPath))
+			return false;
+		variablePut(variableName, newPath);
+		return true;
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
index 5ff5392..7a58ae6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,7 +18,8 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.IDocument;
 
 /**
  * Defines behavior common to all Java Model operations
@@ -198,6 +199,12 @@
 			progressMonitor.beginTask(name, totalWork);
 		}
 	}
+	/*
+	 * Returns whether this operation can modify the package fragment roots.
+	 */
+	protected boolean canModifyRoots() {
+		return false;
+	}
 	/**
 	 * Checks with the progress monitor to see whether this operation
 	 * should be canceled. An operation should regularly call this method
@@ -208,7 +215,7 @@
 	 */
 	protected void checkCanceled() {
 		if (isCanceled()) {
-			throw new OperationCanceledException(Util.bind("operation.cancelled")); //$NON-NLS-1$
+			throw new OperationCanceledException(Messages.operation_cancelled); 
 		}
 	}
 	/**
@@ -265,7 +272,7 @@
 				forceFlag ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY,
 				true, // local
 				getSubProgressMonitor(1));
-				this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
+			this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
 		} catch (CoreException e) {
 			throw new JavaModelException(e);
 		}
@@ -415,6 +422,15 @@
 		}
 		return stack;
 	}
+	/*
+	 * Returns the existing document for the given cu, or a DocumentAdapter if none.
+	 */
+	protected IDocument getDocument(ICompilationUnit cu) throws JavaModelException {
+		IBuffer buffer = cu.getBuffer();
+		if (buffer instanceof IDocument)
+			return (IDocument) buffer;
+		return new DocumentAdapter(buffer);
+	}
 	/**
 	 * Returns the elements to which this operation applies,
 	 * or <code>null</code> if not applicable.
@@ -693,9 +709,11 @@
 			progressMonitor = monitor;
 			pushOperation(this);
 			try {
-				// computes the root infos before executing the operation
-				// noop if aready initialized
-				JavaModelManager.getJavaModelManager().deltaState.initializeRoots();
+				if (canModifyRoots()) {
+					// computes the root infos before executing the operation
+					// noop if aready initialized
+					JavaModelManager.getJavaModelManager().deltaState.initializeRoots();
+				}
 				
 				executeOperation();
 			} finally {
@@ -705,11 +723,31 @@
 			}
 		} finally {
 			try {
+				// reacquire delta processor as it can have been reset during executeOperation()
+				deltaProcessor = manager.getDeltaProcessor();
+				
 				// update JavaModel using deltas that were recorded during this operation
 				for (int i = previousDeltaCount, size = deltaProcessor.javaModelDeltas.size(); i < size; i++) {
 					deltaProcessor.updateJavaModel((IJavaElementDelta)deltaProcessor.javaModelDeltas.get(i));
 				}
 				
+				// close the parents of the created elements and reset their project's cache (in case we are in an 
+				// IWorkspaceRunnable and the clients wants to use the created element's parent)
+				// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=83646
+				for (int i = 0, length = this.resultElements.length; i < length; i++) {
+					IJavaElement element = this.resultElements[i];
+					Openable openable = (Openable) element.getOpenable();
+					if (!(openable instanceof CompilationUnit) || !((CompilationUnit) openable).isWorkingCopy()) { // a working copy must remain a child of its parent even after a move
+						((JavaElement) openable.getParent()).close();
+					}
+					switch (element.getElementType()) {
+						case IJavaElement.PACKAGE_FRAGMENT_ROOT:
+						case IJavaElement.PACKAGE_FRAGMENT:
+							((JavaProject) element.getJavaProject()).resetCaches();
+							break;
+					}
+				}
+				
 				// fire only iff:
 				// - the operation is a top level operation
 				// - the operation did produce some delta(s)
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java
index 91eea48..5f2895b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelStatus.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,7 +24,7 @@
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * @see IJavaModelStatus
@@ -56,7 +56,7 @@
 	/**
 	 * Singleton OK object
 	 */
-	public static final IJavaModelStatus VERIFIED_OK = new JavaModelStatus(OK, OK, Util.bind("status.OK")); //$NON-NLS-1$
+	public static final IJavaModelStatus VERIFIED_OK = new JavaModelStatus(OK, OK, Messages.status_OK); 
 
 	/**
 	 * Constructs an Java model status with no corresponding elements.
@@ -176,40 +176,40 @@
 		if (exception == null) {
 			switch (getCode()) {
 				case CORE_EXCEPTION :
-					return Util.bind("status.coreException"); //$NON-NLS-1$
+					return Messages.status_coreException; 
 
 				case BUILDER_INITIALIZATION_ERROR:
-					return Util.bind("build.initializationError"); //$NON-NLS-1$
+					return Messages.build_initializationError; 
 
 				case BUILDER_SERIALIZATION_ERROR:
-					return Util.bind("build.serializationError"); //$NON-NLS-1$
+					return Messages.build_serializationError; 
 
 				case DEVICE_PATH:
-					return Util.bind("status.cannotUseDeviceOnPath", getPath().toString()); //$NON-NLS-1$
+					return Messages.bind(Messages.status_cannotUseDeviceOnPath, getPath().toString()); 
 
 				case DOM_EXCEPTION:
-					return Util.bind("status.JDOMError"); //$NON-NLS-1$
+					return Messages.status_JDOMError; 
 
 				case ELEMENT_DOES_NOT_EXIST:
-					return Util.bind("element.doesNotExist",((JavaElement)elements[0]).toStringWithAncestors()); //$NON-NLS-1$
+					return Messages.bind(Messages.element_doesNotExist, ((JavaElement)elements[0]).toStringWithAncestors()); 
 
 				case ELEMENT_NOT_ON_CLASSPATH:
-					return Util.bind("element.notOnClasspath",((JavaElement)elements[0]).toStringWithAncestors()); //$NON-NLS-1$
+					return Messages.bind(Messages.element_notOnClasspath, ((JavaElement)elements[0]).toStringWithAncestors()); 
 
 				case EVALUATION_ERROR:
-					return Util.bind("status.evaluationError", string); //$NON-NLS-1$
+					return Messages.bind(Messages.status_evaluationError, string); 
 
 				case INDEX_OUT_OF_BOUNDS:
-					return Util.bind("status.indexOutOfBounds"); //$NON-NLS-1$
+					return Messages.status_indexOutOfBounds; 
 
 				case INVALID_CONTENTS:
-					return Util.bind("status.invalidContents"); //$NON-NLS-1$
+					return Messages.status_invalidContents; 
 
 				case INVALID_DESTINATION:
-					return Util.bind("status.invalidDestination", ((JavaElement)elements[0]).toStringWithAncestors()); //$NON-NLS-1$
+					return Messages.bind(Messages.status_invalidDestination, ((JavaElement)elements[0]).toStringWithAncestors()); 
 
 				case INVALID_ELEMENT_TYPES:
-					StringBuffer buff= new StringBuffer(Util.bind("operation.notSupported")); //$NON-NLS-1$
+					StringBuffer buff= new StringBuffer(Messages.operation_notSupported); 
 					for (int i= 0; i < elements.length; i++) {
 						if (i > 0) {
 							buff.append(", "); //$NON-NLS-1$
@@ -219,83 +219,86 @@
 					return buff.toString();
 
 				case INVALID_NAME:
-					return Util.bind("status.invalidName", string); //$NON-NLS-1$
+					return Messages.bind(Messages.status_invalidName, string); 
 
 				case INVALID_PACKAGE:
-					return Util.bind("status.invalidPackage", string); //$NON-NLS-1$
+					return Messages.bind(Messages.status_invalidPackage, string); 
 
 				case INVALID_PATH:
 					if (string != null) {
 						return string;
 					} else {
-						return Util.bind("status.invalidPath", getPath() == null ? "null" : getPath().toString()); //$NON-NLS-1$ //$NON-NLS-2$
+						return Messages.bind(
+							Messages.status_invalidPath,
+							new String[] {getPath() == null ? "null" : getPath().toString()} //$NON-NLS-1$
+						); 
 					}
 
 				case INVALID_PROJECT:
-					return Util.bind("status.invalidProject", string); //$NON-NLS-1$
+					return Messages.bind(Messages.status_invalidProject, string); 
 
 				case INVALID_RESOURCE:
-					return Util.bind("status.invalidResource", string); //$NON-NLS-1$
+					return Messages.bind(Messages.status_invalidResource, string); 
 
 				case INVALID_RESOURCE_TYPE:
-					return Util.bind("status.invalidResourceType", string); //$NON-NLS-1$
+					return Messages.bind(Messages.status_invalidResourceType, string); 
 
 				case INVALID_SIBLING:
 					if (string != null) {
-						return Util.bind("status.invalidSibling", string); //$NON-NLS-1$
+						return Messages.bind(Messages.status_invalidSibling, string); 
 					} else {
-						return Util.bind("status.invalidSibling", ((JavaElement)elements[0]).toStringWithAncestors()); //$NON-NLS-1$
+						return Messages.bind(Messages.status_invalidSibling, ((JavaElement)elements[0]).toStringWithAncestors()); 
 					}
 
 				case IO_EXCEPTION:
-					return Util.bind("status.IOException"); //$NON-NLS-1$
+					return Messages.status_IOException; 
 
 				case NAME_COLLISION:
 					if (elements != null && elements.length > 0) {
 						IJavaElement element = elements[0];
 						if (element instanceof PackageFragment && ((PackageFragment) element).isDefaultPackage()) {
-							return Util.bind("operation.cannotRenameDefaultPackage"); //$NON-NLS-1$
+							return Messages.operation_cannotRenameDefaultPackage; 
 						}
 					}
 					if (string != null) {
 						return string;
 					} else {
-						return Util.bind("status.nameCollision", ""); //$NON-NLS-1$ //$NON-NLS-2$
+						return Messages.bind(Messages.status_nameCollision, "");  //$NON-NLS-1$
 					}
 				case NO_ELEMENTS_TO_PROCESS:
-					return Util.bind("operation.needElements"); //$NON-NLS-1$
+					return Messages.operation_needElements; 
 
 				case NULL_NAME:
-					return Util.bind("operation.needName"); //$NON-NLS-1$
+					return Messages.operation_needName; 
 
 				case NULL_PATH:
-					return Util.bind("operation.needPath"); //$NON-NLS-1$
+					return Messages.operation_needPath; 
 
 				case NULL_STRING:
-					return Util.bind("operation.needString"); //$NON-NLS-1$
+					return Messages.operation_needString; 
 
 				case PATH_OUTSIDE_PROJECT:
-					return Util.bind("operation.pathOutsideProject", string, ((JavaElement)elements[0]).toStringWithAncestors()); //$NON-NLS-1$
+					return Messages.bind(Messages.operation_pathOutsideProject, new String[] {string, ((JavaElement)elements[0]).toStringWithAncestors()}); 
 
 				case READ_ONLY:
 					IJavaElement element = elements[0];
 					String name = element.getElementName();
 					if (element instanceof IPackageFragment && name.equals(IPackageFragment.DEFAULT_PACKAGE_NAME)) {
-						return Util.bind("status.defaultPackageReadOnly"); //$NON-NLS-1$
+						return Messages.status_defaultPackageReadOnly; 
 					}
-					return  Util.bind("status.readOnly", name); //$NON-NLS-1$
+					return Messages.bind(Messages.status_readOnly, name); 
 
 				case RELATIVE_PATH:
-					return Util.bind("operation.needAbsolutePath", getPath().toString()); //$NON-NLS-1$
+					return Messages.bind(Messages.operation_needAbsolutePath, getPath().toString()); 
 
 				case TARGET_EXCEPTION:
-					return Util.bind("status.targetException"); //$NON-NLS-1$
+					return Messages.status_targetException; 
 
 				case UPDATE_CONFLICT:
-					return Util.bind("status.updateConflict"); //$NON-NLS-1$
+					return Messages.status_updateConflict; 
 
 				case NO_LOCAL_CONTENTS :
-					return Util.bind("status.noLocalContents", getPath().toString()); //$NON-NLS-1$
+					return Messages.bind(Messages.status_noLocalContents, getPath().toString()); 
 
 				case CP_CONTAINER_PATH_UNBOUND:
 					IJavaProject javaProject = (IJavaProject)elements[0];
@@ -303,7 +306,7 @@
 					String description = null;
 					if (initializer != null) description = initializer.getDescription(this.path, javaProject);
 					if (description == null) description = path.makeRelative().toString();
-					return Util.bind("classpath.unboundContainerPath", description, javaProject.getElementName()); //$NON-NLS-1$
+					return Messages.bind(Messages.classpath_unboundContainerPath, new String[] {description, javaProject.getElementName()}); 
 
 				case INVALID_CP_CONTAINER_ENTRY:
 					javaProject = (IJavaProject)elements[0];
@@ -321,15 +324,15 @@
 						description = container.getDescription();
 					}
 					if (description == null) description = path.makeRelative().toString();
-					return Util.bind("classpath.invalidContainer", description, javaProject.getElementName()); //$NON-NLS-1$
+					return Messages.bind(Messages.classpath_invalidContainer, new String[] {description, javaProject.getElementName()}); 
 
 			case CP_VARIABLE_PATH_UNBOUND:
 				javaProject = (IJavaProject)elements[0];
-				return Util.bind("classpath.unboundVariablePath", path.makeRelative().toString(), javaProject.getElementName()); //$NON-NLS-1$
+				return Messages.bind(Messages.classpath_unboundVariablePath, new String[] {path.makeRelative().toString(), javaProject.getElementName()}); 
 					
 			case CLASSPATH_CYCLE: 
 				javaProject = (IJavaProject)elements[0];
-				return Util.bind("classpath.cycle", javaProject.getElementName()); //$NON-NLS-1$
+				return Messages.bind(Messages.classpath_cycle, javaProject.getElementName()); 
 												 
 			case DISABLED_CP_EXCLUSION_PATTERNS:
 				javaProject = (IJavaProject)elements[0];
@@ -338,7 +341,7 @@
 				if (path.segment(0).toString().equals(projectName)) {
 					newPath = path.removeFirstSegments(1);
 				}
-				return Util.bind("classpath.disabledInclusionExclusionPatterns", newPath.makeRelative().toString(), projectName); //$NON-NLS-1$
+				return Messages.bind(Messages.classpath_disabledInclusionExclusionPatterns, new String[] {newPath.makeRelative().toString(), projectName}); 
 
 			case DISABLED_CP_MULTIPLE_OUTPUT_LOCATIONS:
 				javaProject = (IJavaProject)elements[0];
@@ -347,11 +350,11 @@
 				if (path.segment(0).toString().equals(projectName)) {
 					newPath = path.removeFirstSegments(1);
 				}
-				return Util.bind("classpath.disabledMultipleOutputLocations", newPath.makeRelative().toString(), projectName); //$NON-NLS-1$
+				return Messages.bind(Messages.classpath_disabledMultipleOutputLocations, new String[] {newPath.makeRelative().toString(), projectName}); 
 
 			case INCOMPATIBLE_JDK_LEVEL:
 					javaProject = (IJavaProject)elements[0];
-					return Util.bind("classpath.incompatibleLibraryJDKLevel", new String[]{	//$NON-NLS-1$
+					return Messages.bind(Messages.classpath_incompatibleLibraryJDKLevel, new String[]{	
 						javaProject.getElementName(), 
 						javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true), 
 						path.makeRelative().toString(),
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index 526681f..989536d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -71,6 +71,7 @@
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.eval.EvaluationContextWrapper;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 import org.eclipse.jdt.internal.eval.EvaluationContext;
 import org.osgi.service.prefs.BackingStoreException;
@@ -383,10 +384,11 @@
 	 */
 	public void computeChildren(JavaProjectElementInfo info) throws JavaModelException {
 		IClasspathEntry[] classpath = getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
-		IPackageFragmentRoot[] oldRoots = info.allPkgFragmentRootsCache;
-		if (oldRoots != null) {
+		JavaProjectElementInfo.ProjectCache projectCache = info.projectCache;
+		if (projectCache != null) {
 			IPackageFragmentRoot[] newRoots = computePackageFragmentRoots(classpath, true, null /*no reverse map*/);
 			checkIdentical: { // compare all pkg fragment root lists
+				IPackageFragmentRoot[] oldRoots = projectCache.allPkgFragmentRootsCache;
 				if (oldRoots.length == newRoots.length){
 					for (int i = 0, length = oldRoots.length; i < length; i++){
 						if (!oldRoots[i].equals(newRoots[i])){
@@ -397,7 +399,6 @@
 				}	
 			}
 		}
-		info.resetCaches(); // discard caches (hold onto roots and pkg fragments)
 		info.setNonJavaResources(null);
 		info.setChildren(
 			computePackageFragmentRoots(classpath, false, null /*no reverse map*/));		
@@ -574,7 +575,7 @@
 							requiredProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/), 
 							accumulatedRoots, 
 							rootIDs, 
-							rootToResolvedEntries == null ? resolvedEntry : ((ClasspathEntry)resolvedEntry).combineWith(referringEntry), // only combine if need to build the reverse map 
+							rootToResolvedEntries == null ? resolvedEntry : ((ClasspathEntry)resolvedEntry).combineWith((ClasspathEntry) referringEntry), // only combine if need to build the reverse map 
 							checkExistency, 
 							retrieveExportedRoots,
 							rootToResolvedEntries);
@@ -585,7 +586,7 @@
 		if (root != null) {
 			accumulatedRoots.add(root);
 			rootIDs.add(rootID);
-			if (rootToResolvedEntries != null) rootToResolvedEntries.put(root, ((ClasspathEntry)resolvedEntry).combineWith(referringEntry));
+			if (rootToResolvedEntries != null) rootToResolvedEntries.put(root, ((ClasspathEntry)resolvedEntry).combineWith((ClasspathEntry) referringEntry));
 		}
 	}
 	
@@ -792,7 +793,7 @@
 				new Object[] {
 					status.getMessage(),
 					new Integer(severity), 
-					Util.bind("classpath.buildPath"),//$NON-NLS-1$
+					Messages.classpath_buildPath,
 					isCycleProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
 					isClasspathFileFormatProblem ? "true" : "false",//$NON-NLS-1$ //$NON-NLS-2$
 					new Integer(status.getCode()),
@@ -831,15 +832,15 @@
 					DocumentBuilderFactory.newInstance().newDocumentBuilder();
 				cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
 			} catch (SAXException e) {
-				throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+				throw new IOException(Messages.file_badFormat); 
 			} catch (ParserConfigurationException e) {
-				throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+				throw new IOException(Messages.file_badFormat); 
 			} finally {
 				reader.close();
 			}
 	
 			if (!cpElement.getNodeName().equalsIgnoreCase("classpath")) { //$NON-NLS-1$
-				throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+				throw new IOException(Messages.file_badFormat); 
 			}
 			NodeList list = cpElement.getElementsByTagName("classpathentry"); //$NON-NLS-1$
 			int length = list.getLength();
@@ -862,7 +863,7 @@
 			if (createMarker && this.project.isAccessible()) {
 					this.createClasspathProblemMarker(new JavaModelStatus(
 							IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-							Util.bind("classpath.xmlFormatError", this.getElementName(), e.getMessage()))); //$NON-NLS-1$
+							Messages.bind(Messages.classpath_xmlFormatError, (new String[] {this.getElementName(), e.getMessage()})))); 
 			}
 			if (logProblems) {
 				Util.log(e, 
@@ -875,7 +876,7 @@
 			if (createMarker && this.project.isAccessible()) {
 				this.createClasspathProblemMarker(new JavaModelStatus(
 						IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-						Util.bind("classpath.illegalEntryInClasspathFile", this.getElementName(), e.getMessage()))); //$NON-NLS-1$
+						Messages.bind(Messages.classpath_illegalEntryInClasspathFile, (new String[] {this.getElementName(), e.getMessage()})))); 
 			}
 			if (logProblems) {
 				Util.log(e, 
@@ -884,15 +885,12 @@
 			}
 			return INVALID_CLASSPATH;
 		}
+		// return an empty classpath is it size is 0, to differenciate from a null classpath
 		int pathSize = paths.size();
-		if (pathSize > 0 || defaultOutput != null) {
-			IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)];
-			paths.toArray(entries);
-			if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item
-			return entries;
-		} else {
-			return null;
-		}
+		IClasspathEntry[] entries = new IClasspathEntry[pathSize + (defaultOutput == null ? 0 : 1)];
+		paths.toArray(entries);
+		if (defaultOutput != null) entries[pathSize] = defaultOutput; // ensure output is last item
+		return entries;
 	}
 
 	/**
@@ -1093,7 +1091,7 @@
 
 		IPackageFragmentRoot[] allRoots = this.getAllPackageFragmentRoots();
 		if (!path.isAbsolute()) {
-			throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.path_mustBeAbsolute); 
 		}
 		for (int i= 0; i < allRoots.length; i++) {
 			IPackageFragmentRoot classpathRoot= allRoots[i];
@@ -1249,7 +1247,7 @@
 
 			// will force an update of the classpath/output location based on the file information
 			// extract out the output location
-			IPath outputLocation = SetClasspathOperation.REUSE_PATH; 
+			IPath outputLocation = SetClasspathOperation.DO_NOT_SET_OUTPUT; 
 			if (fileEntries != null && fileEntries.length > 0) {
 				IClasspathEntry entry = fileEntries[fileEntries.length - 1];
 				if (entry.getContentKind() == ClasspathEntry.K_OUTPUT) {
@@ -1284,11 +1282,11 @@
 						// happens if the .classpath could not be written to disk
 						createClasspathProblemMarker(new JavaModelStatus(
 								IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-								Util.bind("classpath.couldNotWriteClasspathFile", getElementName(), e.getMessage()))); //$NON-NLS-1$
+								Messages.bind(Messages.classpath_couldNotWriteClasspathFile, new String[] {getElementName(), e.getMessage()}))); 
 					} else {
 						createClasspathProblemMarker(new JavaModelStatus(
 								IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-								Util.bind("classpath.invalidClasspathInClasspathFile", getElementName(), e.getMessage()))); //$NON-NLS-1$
+								Messages.bind(Messages.classpath_invalidClasspathInClasspathFile, new String[] {getElementName(), e.getMessage()}))); 
 					}			
 				}
 			}
@@ -1382,7 +1380,7 @@
 	 * Returns the project custom preference pool.
 	 * Project preferences may include custom encoding.
 	 * @return IEclipsePreferences
-	 */	
+	 */
 	public IEclipsePreferences getEclipsePreferences(){
 		if (!JavaProject.hasJavaNature(this.project)) return null;
 		// Get cached preferences if exist
@@ -1393,8 +1391,9 @@
 		final IEclipsePreferences eclipsePreferences = context.getNode(JavaCore.PLUGIN_ID);
 		updatePreferences(eclipsePreferences);
 		perProjectInfo.preferences = eclipsePreferences;
+
 		// Listen to node removal from parent in order to reset cache (see bug 68993)
-		IEclipsePreferences.INodeChangeListener listener = new IEclipsePreferences.INodeChangeListener() {
+		IEclipsePreferences.INodeChangeListener nodeListener = new IEclipsePreferences.INodeChangeListener() {
 			public void added(IEclipsePreferences.NodeChangeEvent event) {
 				// do nothing
 			}
@@ -1404,7 +1403,15 @@
 				}
 			}
 		};
-		((IEclipsePreferences) eclipsePreferences.parent()).addNodeChangeListener(listener);
+		((IEclipsePreferences) eclipsePreferences.parent()).addNodeChangeListener(nodeListener);
+
+		// Listen to preference changes
+		IEclipsePreferences.IPreferenceChangeListener preferenceListener = new IEclipsePreferences.IPreferenceChangeListener() {
+			public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) {
+				JavaModelManager.getJavaModelManager().resetProjectOptions(JavaProject.this);
+			}
+		};
+		eclipsePreferences.addPreferenceChangeListener(preferenceListener);
 		return eclipsePreferences;
 	}
 
@@ -1544,10 +1551,10 @@
 		
 		String propertyName = optionName;
 		if (JavaModelManager.getJavaModelManager().optionNames.contains(propertyName)){
-			IEclipsePreferences preferences = getEclipsePreferences();
+			IEclipsePreferences projectPreferences = getEclipsePreferences();
 			String javaCoreDefault = inheritJavaCoreOptions ? JavaCore.getOption(propertyName) : null;
-			if (preferences == null) return javaCoreDefault;
-			String value = preferences.get(propertyName, javaCoreDefault);
+			if (projectPreferences == null) return javaCoreDefault;
+			String value = projectPreferences.get(propertyName, javaCoreDefault);
 			return value == null ? null : value.trim();
 		}
 		return null;
@@ -1557,31 +1564,53 @@
 	 * @see org.eclipse.jdt.core.IJavaProject#getOptions(boolean)
 	 */
 	public Map getOptions(boolean inheritJavaCoreOptions) {
-		
+
 		// initialize to the defaults from JavaCore options pool
 		Map options = inheritJavaCoreOptions ? JavaCore.getOptions() : new Hashtable(5);
 
-		IEclipsePreferences preferences = getEclipsePreferences();
-		if (preferences == null) return options; // cannot do better (non-Java project)
+		// Get project specific options
+		JavaModelManager.PerProjectInfo perProjectInfo = null;
+		Hashtable projectOptions = null;
 		HashSet optionNames = JavaModelManager.getJavaModelManager().optionNames;
-		
-		// project cannot hold custom preferences set to their default, as it uses CUSTOM_DEFAULT_OPTION_VALUE
-
-		// get custom preferences not set to their default
 		try {
-			String[] propertyNames = preferences.keys();
-			for (int i = 0; i < propertyNames.length; i++){
-				String propertyName = propertyNames[i];
-				String value = preferences.get(propertyName, null);
-				if (value != null && optionNames.contains(propertyName)){
-					options.put(propertyName, value.trim());
-				}
-			}		
+			perProjectInfo = getPerProjectInfo();
+			projectOptions = perProjectInfo.options;
+			if (projectOptions == null) {
+				// get eclipse preferences
+				IEclipsePreferences projectPreferences= getEclipsePreferences();
+				if (projectPreferences == null) return options; // cannot do better (non-Java project)
+				// create project options
+				String[] propertyNames = projectPreferences.keys();
+				projectOptions = new Hashtable(propertyNames.length);
+				for (int i = 0; i < propertyNames.length; i++){
+					String propertyName = propertyNames[i];
+					String value = projectPreferences.get(propertyName, null);
+					if (value != null && optionNames.contains(propertyName)){
+						projectOptions.put(propertyName, value.trim());
+					}
+				}		
+				// cache project options
+				perProjectInfo.options = projectOptions;
+			}
+		} catch (JavaModelException jme) {
+			projectOptions = new Hashtable();
 		} catch (BackingStoreException e) {
-			// nothing to do
+			projectOptions = new Hashtable();
 		}
 
-		return options;
+		// Inherit from JavaCore options if specified
+		if (inheritJavaCoreOptions) {
+			Iterator propertyNames = projectOptions.keySet().iterator();
+			while (propertyNames.hasNext()) {
+				String propertyName = (String) propertyNames.next();
+				String propertyValue = (String) perProjectInfo.options.get(propertyName);
+				if (propertyValue != null && optionNames.contains(propertyName)){
+					options.put(propertyName, propertyValue.trim());
+				}
+			}
+			return options;
+		}
+		return projectOptions;
 	}
 
 	/**
@@ -1956,7 +1985,7 @@
 					this.flushClasspathProblemMarkers(false, true);
 					this.createClasspathProblemMarker(new JavaModelStatus(
 						IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-						Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
+						Messages.bind(Messages.classpath_cannotReadClasspathFile, this.getElementName()))); 
 			}
 
 			perProjectInfo.resolvedClasspath = resolvedPath;
@@ -2041,13 +2070,13 @@
 
 					// container was bound
 					for (int j = 0, containerLength = containerEntries.length; j < containerLength; j++){
-						ClasspathEntry cEntry = (ClasspathEntry)containerEntries[j];
+						ClasspathEntry cEntry = (ClasspathEntry) containerEntries[j];
 						if (generateMarkerOnError) {
 							IJavaModelStatus containerStatus = ClasspathEntry.validateClasspathEntry(this, cEntry, false, true /*recurse*/);
 							if (!containerStatus.isOK()) createClasspathProblemMarker(containerStatus);
 						}
 						// if container is exported or restricted, then its nested entries must in turn be exported  (21749) and/or propagate restrictions
-						cEntry = cEntry.combineWith(rawEntry);
+						cEntry = cEntry.combineWith((ClasspathEntry) rawEntry);
 						if (rawReverseMap != null) {
 							if (rawReverseMap.get(resolvedPath = cEntry.getPath()) == null) rawReverseMap.put(resolvedPath , rawEntry);
 						}
@@ -2377,11 +2406,11 @@
 		throws JavaModelException {
 
 		if (region == null) {
-			throw new IllegalArgumentException(Util.bind("hierarchy.nullRegion"));//$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
 		}
 		ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
 		CreateTypeHierarchyOperation op =
-			new CreateTypeHierarchyOperation(region, this, workingCopies, null, true);
+			new CreateTypeHierarchyOperation(region, workingCopies, null, true);
 		op.runOperation(monitor);
 		return op.getResult();
 	}
@@ -2409,14 +2438,14 @@
 		throws JavaModelException {
 
 		if (type == null) {
-			throw new IllegalArgumentException(Util.bind("hierarchy.nullFocusType"));//$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.hierarchy_nullFocusType);
 		}
 		if (region == null) {
-			throw new IllegalArgumentException(Util.bind("hierarchy.nullRegion"));//$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
 		}
 		ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
 		CreateTypeHierarchyOperation op =
-			new CreateTypeHierarchyOperation(region, this, workingCopies, type, true);
+			new CreateTypeHierarchyOperation(region, workingCopies, type, true/*compute subtypes*/);
 		op.runOperation(monitor);
 		return op.getResult();
 	}
@@ -2456,7 +2485,7 @@
 				if (createMarker && this.project.isAccessible()) {
 						this.createClasspathProblemMarker(new JavaModelStatus(
 							IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-							Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
+							Messages.bind(Messages.classpath_cannotReadClasspathFile, this.getElementName()))); 
 				}
 				return null;
 			}
@@ -2466,7 +2495,7 @@
 			if (createMarker && this.project.isAccessible()) {
 					this.createClasspathProblemMarker(new JavaModelStatus(
 						IJavaModelStatusConstants.INVALID_CLASSPATH_FILE_FORMAT,
-						Util.bind("classpath.cannotReadClasspathFile", this.getElementName()))); //$NON-NLS-1$
+						Messages.bind(Messages.classpath_cannotReadClasspathFile, this.getElementName()))); 
 			}
 			if (logProblems) {
 				Util.log(e, 
@@ -2659,6 +2688,13 @@
 
 			// persist options
 			projectPreferences.flush();
+			
+			// flush cache immediately
+			try {
+				getPerProjectInfo().options = null;
+			} catch (JavaModelException e) {
+				// do nothing
+			}
 		} catch (BackingStoreException e) {
 			// problem with pref store - quietly ignore
 		}
@@ -2671,12 +2707,12 @@
 		throws JavaModelException {
 
 		if (path == null) {
-			throw new IllegalArgumentException(Util.bind("path.nullPath")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.path_nullPath); 
 		}
 		if (path.equals(getOutputLocation())) {
 			return;
 		}
-		this.setRawClasspath(SetClasspathOperation.REUSE_ENTRIES, path, monitor);
+		this.setRawClasspath(SetClasspathOperation.DO_NOT_SET_ENTRIES, path, monitor);
 	}
 
 	/**
@@ -2754,7 +2790,7 @@
 
 		setRawClasspath(
 			entries, 
-			SetClasspathOperation.REUSE_PATH, 
+			SetClasspathOperation.DO_NOT_SET_OUTPUT, 
 			monitor, 
 			true, // canChangeResource (as per API contract)
 			getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/),
@@ -2898,6 +2934,7 @@
 				try {
 					JavaProjectElementInfo info = getJavaProjectElementInfo();
 					computeChildren(info);
+					info.resetCaches(); // discard caches (hold onto roots and pkg fragments)
 				} catch(JavaModelException e){
 					try {
 						close(); // could not do better
@@ -2931,4 +2968,4 @@
 			}
 		}
 	 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java
index 42a1c88..ca3bb9a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProjectElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -37,23 +37,33 @@
 /* package */
 class JavaProjectElementInfo extends OpenableElementInfo {
 
+	static class ProjectCache {
+		ProjectCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, HashtableOfArrayToObject allPkgFragmentsCache, Map pathToResolvedEntries) {
+			this.allPkgFragmentRootsCache = allPkgFragmentRootsCache;
+			this.allPkgFragmentsCache = allPkgFragmentsCache;
+			this.pathToResolvedEntries = pathToResolvedEntries;
+		}
+		
+		/*
+		 * A cache of all package fragment roots of this project.
+		 */
+		public IPackageFragmentRoot[] allPkgFragmentRootsCache;
+		
+		/*
+		 * A cache of all package fragments in this project.
+		 * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name)
+		 */
+		public HashtableOfArrayToObject allPkgFragmentsCache;
+	
+		public Map pathToResolvedEntries;		
+	}
+	
 	/**
 	 * A array with all the non-java resources contained by this PackageFragment
 	 */
 	private Object[] nonJavaResources;
 	
-	/*
-	 * A cache of all package fragment roots of this project.
-	 */
-	public IPackageFragmentRoot[] allPkgFragmentRootsCache;
-	
-	/*
-	 * A cache of all package fragments in this project.
-	 * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name)
-	 */
-	private HashtableOfArrayToObject allPkgFragmentsCache;
-
-	public Map pathToResolvedEntries;
+	ProjectCache projectCache;
 	
 	/**
 	 * Create and initialize a new instance of the receiver
@@ -164,24 +174,20 @@
 		}
 		return resources;
 	}
-
-	IPackageFragmentRoot[] getAllPackageFragmentRoots(JavaProject project) {
-		if (this.allPkgFragmentRootsCache == null) {
-			try {
-				Map reverseMap = new HashMap(3);
-				this.allPkgFragmentRootsCache = project.getAllPackageFragmentRoots(reverseMap);
-				this.pathToResolvedEntries = reverseMap;
-			} catch (JavaModelException e) {
-				// project does not exist: cannot happend since this is the info of the project
-			}
-		}
-		return this.allPkgFragmentRootsCache;
-	}
 	
-	HashtableOfArrayToObject getAllPackageFragments(JavaProject project) {
-		if (this.allPkgFragmentsCache == null) {
-			HashtableOfArrayToObject cache = new HashtableOfArrayToObject();
-			IPackageFragmentRoot[] roots = getAllPackageFragmentRoots(project);
+	ProjectCache getProjectCache(JavaProject project) {
+		ProjectCache cache = this.projectCache;
+		if (cache == null) {
+			IPackageFragmentRoot[] roots;
+			Map reverseMap = new HashMap(3);
+			try {
+				roots = project.getAllPackageFragmentRoots(reverseMap);
+			} catch (JavaModelException e) {
+				// project does not exist: cannot happen since this is the info of the project
+				roots = new IPackageFragmentRoot[0];
+				reverseMap.clear();
+			}
+			HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject();
 			for (int i = 0, length = roots.length; i < length; i++) {
 				IPackageFragmentRoot root = roots[i];
 				IJavaElement[] frags = null;
@@ -194,21 +200,26 @@
 				for (int j = 0, length2 = frags.length; j < length2; j++) {
 					PackageFragment fragment= (PackageFragment) frags[j];
 					String[] pkgName = fragment.names;
-					IPackageFragmentRoot[] entry= (IPackageFragmentRoot[]) cache.get(pkgName);
-					if (entry == null) {
-						entry= new IPackageFragmentRoot[] {root};
-						cache.put(pkgName, entry);
+					Object existing = fragmentsCache.get(pkgName);
+					if (existing == null) {
+						fragmentsCache.put(pkgName, root);
 					} else {
-						IPackageFragmentRoot[] copy= new IPackageFragmentRoot[entry.length + 1];
-						System.arraycopy(entry, 0, copy, 0, entry.length);
-						copy[entry.length]= root;
-						cache.put(pkgName, copy);
+						if (existing instanceof PackageFragmentRoot) {
+							fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
+						} else {
+							IPackageFragmentRoot[] entry= (IPackageFragmentRoot[]) existing;
+							IPackageFragmentRoot[] copy= new IPackageFragmentRoot[entry.length + 1];
+							System.arraycopy(entry, 0, copy, 0, entry.length);
+							copy[entry.length]= root;
+							fragmentsCache.put(pkgName, copy);
+						}
 					}
 				}
 			}
-			this.allPkgFragmentsCache = cache;
+			cache = new ProjectCache(roots, fragmentsCache, reverseMap);
+			this.projectCache = cache;
 		}
-		return this.allPkgFragmentsCache;
+		return cache;
 	}
 	
 	/**
@@ -245,21 +256,16 @@
 	 * The given project is assumed to be the handle of this info.
 	 * This name lookup first looks in the given working copies.
 	 */
-	synchronized NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
-		// note that this method has to be synchronized so that the field pathToResolvedEntries is not reset while computing the roots and package fragments
-		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=79766)
-		return new NameLookup(getAllPackageFragmentRoots(project), getAllPackageFragments(project), workingCopies, this.pathToResolvedEntries);
+	NameLookup newNameLookup(JavaProject project, ICompilationUnit[] workingCopies) {
+		ProjectCache cache = getProjectCache(project);
+		return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.pathToResolvedEntries);
 	}
 	
 	/*
 	 * Reset the package fragment roots and package fragment caches
 	 */
-	synchronized void resetCaches() {
-		// note that this method has to be synchronized so that the field pathToResolvedEntries is not reset while computing the roots and package fragments
-		// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=79766)
-		this.allPkgFragmentRootsCache = null;
-		this.allPkgFragmentsCache = null;
-		this.pathToResolvedEntries = null;
+	void resetCaches() {
+		this.projectCache = null;
 	}
 	
 	/**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java
index bddecbb..a1b8cf8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LRUCacheEnumerator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
index d1f7036..b7cd37e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
index bb04b9e..e30ad29 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -22,7 +22,6 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
-import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
@@ -92,14 +91,6 @@
 			return null;
 	}
 }
-/**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	return getElementName().equals(node.getName());
-}
 /*
  * Helper method for SourceType.findMethods and BinaryType.findMethods
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java
index ae91903..9dbb32c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MemberElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java
index e52e7a3..edd4215 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModelUpdater.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java
index d6f28bd..e613044 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveElementsOperation.java
@@ -1,17 +1,17 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
 import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * This operation moves elements from their current
@@ -35,7 +35,7 @@
  * for progress monitoring.
  */
 protected String getMainTaskName() {
-	return Util.bind("operation.moveElementProgress"); //$NON-NLS-1$
+	return Messages.operation_moveElementProgress; 
 }
 /**
  * @see CopyElementsOperation#isMove()
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java
index 26338c0..1e669d4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MovePackageFragmentRootOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java
index 73c8f71..3cde822 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MoveResourceElementsOperation.java
@@ -1,17 +1,17 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
 import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * This operation moves resources (package fragments and compilation units) from their current
@@ -34,7 +34,7 @@
  * @see MultiOperation
  */
 protected String getMainTaskName() {
-	return Util.bind("operation.moveResourceProgress"); //$NON-NLS-1$
+	return Messages.operation_moveResourceProgress; 
 }
 /**
  * @see CopyResourceElementsOperation#isMove()
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java
index cef01a8..898192e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/MultiOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -103,11 +103,13 @@
 	 * Returns the new name for <code>element</code>, or <code>null</code>
 	 * if there are no renamings specified.
 	 */
-	protected String getNewNameFor(IJavaElement element) {
+	protected String getNewNameFor(IJavaElement element) throws JavaModelException {
+		String newName = null;
 		if (this.renamings != null)
-			return (String) this.renamings.get(element);
-		else
-			return null;
+			newName = (String) this.renamings.get(element);
+		if (newName == null && element instanceof IMethod && ((IMethod) element).isConstructor())
+			newName = getDestinationParent(element).getElementName();
+		return newName;
 	}
 	/**
 	 * Sets up the renamings hashtable - keys are the elements and
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
index 40a999e..504a766 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -35,13 +35,14 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.*;
 import org.eclipse.jdt.core.search.IJavaSearchConstants;
-import org.eclipse.jdt.core.search.ITypeNameRequestor;
 import org.eclipse.jdt.core.search.SearchEngine;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -98,10 +99,12 @@
 
 	/**
 	 * Table that maps package names to lists of package fragment roots
-	 * that contain such a package known
-	 * by this name lookup facility. To allow > 1 package fragment
-	 * with the same name, values are arrays of package fragment roots
-	 * ordered as they appear on the classpath.
+	 * that contain such a package known by this name lookup facility. 
+	 * To allow > 1 package fragment with the same name, values are 
+	 * arrays of package fragment roots ordered as they appear on the 
+	 * classpath.
+	 * Note if the list is of size 1, then the IPackageFragmentRoot object
+	 * replaces the array.
 	 */
 	protected HashtableOfArrayToObject packageFragments;
 
@@ -118,6 +121,7 @@
 	protected HashMap unitsToLookInside;
 	
 	public long timeSpentInSeekTypesInSourcePackage = 0;
+	public long timeSpentInSeekTypesInBinaryPackage = 0;
 
 	public NameLookup(IPackageFragmentRoot[] packageFragmentRoots, HashtableOfArrayToObject packageFragments, ICompilationUnit[] workingCopies, Map rootToResolvedEntries) {
 		if (VERBOSE) {
@@ -169,14 +173,19 @@
 				IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
 				if (visited.contains(root)) continue;
 				String[] pkgName = pkg.names;
-				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) packageFragments.get(pkgName);
-				if (roots == null) {
-					this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {root});
+				Object existing = this.packageFragments.get(pkgName);
+				if (existing == null) {
+					this.packageFragments.put(pkgName, root);
 				} else {
-					int rootLength = roots.length;
-					System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
-					roots[rootLength] = root;
-					this.packageFragments.put(pkgName, roots);
+					if (existing instanceof PackageFragmentRoot) {
+						this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root});
+					} else {
+						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing;
+						int rootLength = roots.length;
+						System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength);
+						roots[rootLength] = root;
+						this.packageFragments.put(pkgName, roots);
+					}
 				}
 				visited.add(root);
 			}
@@ -270,29 +279,41 @@
 		if (index != -1) {
 			cuName= cuName.substring(0, index);
 		}
-		IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) this.packageFragments.get(pkgName);
-		if (roots != null) {
-			for (int i= 0; i < roots.length; i++) {
-				PackageFragmentRoot root= (PackageFragmentRoot) roots[i];
-				if (!root.isArchive()) {
-					IPackageFragment pkg = root.getPackageFragment(pkgName);
-					try {
-						ICompilationUnit[] cus = pkg.getCompilationUnits();
-						for (int j = 0, length = cus.length; j < length; j++) {
-							ICompilationUnit cu = cus[j];
-							if (Util.equalsIgnoreJavaLikeExtension(cu.getElementName(), cuName))
-								return cu;
-						}
-					} catch (JavaModelException e) {
-						// pkg does not exist
-						// -> try next package
-					}
+		Object value = this.packageFragments.get(pkgName);
+		if (value != null) {
+			if (value instanceof PackageFragmentRoot) {
+				return findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) value);
+			} else {
+				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+				for (int i= 0; i < roots.length; i++) {
+					PackageFragmentRoot root= (PackageFragmentRoot) roots[i];
+					ICompilationUnit cu = findCompilationUnit(pkgName, cuName, root);
+					if (cu != null)
+						return cu;
 				}
 			}
 		}
 		return null;
 	}
 	
+	private ICompilationUnit findCompilationUnit(String[] pkgName, String cuName, PackageFragmentRoot root) {
+		if (!root.isArchive()) {
+			IPackageFragment pkg = root.getPackageFragment(pkgName);
+			try {
+				ICompilationUnit[] cus = pkg.getCompilationUnits();
+				for (int j = 0, length = cus.length; j < length; j++) {
+					ICompilationUnit cu = cus[j];
+					if (Util.equalsIgnoreJavaLikeExtension(cu.getElementName(), cuName))
+						return cu;
+				}
+			} catch (JavaModelException e) {
+				// pkg does not exist
+				// -> try next package
+			}
+		}
+		return null;
+}
+	
 	/**
 	 * Returns the package fragment whose path matches the given
 	 * (absolute) path, or <code>null</code> if none exist. The domain of
@@ -304,7 +325,7 @@
 	 */
 	public IPackageFragment findPackageFragment(IPath path) {
 		if (!path.isAbsolute()) {
-			throw new IllegalArgumentException(Util.bind("path.mustBeAbsolute")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.path_mustBeAbsolute); 
 		}
 /*
  * TODO (jerome) this code should rather use the package fragment map to find the candidate package, then
@@ -396,10 +417,9 @@
 			for (int i = 0, length = keys.length; i < length; i++) {
 				String[] pkgName = (String[]) keys[i];
 				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
-					IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) this.packageFragments.valueTable[i];
-					for (int j = 0, length2 = roots.length; j < length2; j++) {
-						PackageFragmentRoot root = (PackageFragmentRoot) roots[j];
-						IPackageFragment pkg = root.getPackageFragment(pkgName);
+					Object value = this.packageFragments.valueTable[i];
+					if (value instanceof PackageFragmentRoot) {
+						IPackageFragment pkg = ((PackageFragmentRoot) value).getPackageFragment(pkgName);
 						if (oneFragment == null) {
 							oneFragment = new IPackageFragment[] {pkg};
 						} else {
@@ -409,6 +429,21 @@
 							}
 							pkgs.add(pkg);
 						}
+					} else {
+						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+						for (int j = 0, length2 = roots.length; j < length2; j++) {
+							PackageFragmentRoot root = (PackageFragmentRoot) roots[j];
+							IPackageFragment pkg = root.getPackageFragment(pkgName);
+							if (oneFragment == null) {
+								oneFragment = new IPackageFragment[] {pkg};
+							} else {
+								if (pkgs == null) {
+									pkgs = new ArrayList();
+									pkgs.add(oneFragment[0]);
+								}
+								pkgs.add(pkg);
+							}
+						}
 					}
 				}
 			}
@@ -419,13 +454,18 @@
 			return result;
 		} else {
 			String[] splittedName = Util.splitOn('.', name, 0, name.length());
-			IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) this.packageFragments.get(splittedName);
-			if (roots != null) {
-				IPackageFragment[] result = new IPackageFragment[roots.length];
-				for (int i= 0; i < roots.length; i++) {
-					result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName);
+			Object value = this.packageFragments.get(splittedName);
+			if (value instanceof PackageFragmentRoot) {
+				return new IPackageFragment[] {((PackageFragmentRoot) value).getPackageFragment(splittedName)};
+			} else {
+				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+				if (roots != null) {
+					IPackageFragment[] result = new IPackageFragment[roots.length];
+					for (int i= 0; i < roots.length; i++) {
+						result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName);
+					}
+					return result;
 				}
-				return result;
 			}
 		}
 		return null;
@@ -498,16 +538,26 @@
 	IType findSecondaryType(String typeName, IPackageFragment pkg, boolean partialMatch, final int acceptFlags) {
 		try {
 			final ArrayList paths = new ArrayList();
-			ITypeNameRequestor nameRequestor = new ITypeNameRequestor() {
-				public void acceptClass(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
-					if ((acceptFlags & ACCEPT_CLASSES) != 0)
-						if (enclosingTypeNames == null || enclosingTypeNames.length == 0) // accept only top level types
-							paths.add(path);
-				}
-				public void acceptInterface(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
-					if ((acceptFlags & ACCEPT_INTERFACES) != 0)
-						if (enclosingTypeNames == null || enclosingTypeNames.length == 0) // accept only top level types
-							paths.add(path);
+			TypeNameRequestor nameRequestor = new TypeNameRequestor() {
+				public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
+					if (enclosingTypeNames == null || enclosingTypeNames.length == 0) { // accept only top level types
+						int kind = modifiers & (IConstants.AccInterface+IConstants.AccEnum+IConstants.AccAnnotation);
+						switch (kind) {
+							case IConstants.AccAnnotation:
+							case IConstants.AccAnnotation+IConstants.AccInterface:
+								if ((acceptFlags & ACCEPT_ANNOTATIONS) != 0) paths.add(path);
+								break;
+							case IConstants.AccEnum:
+								if ((acceptFlags & ACCEPT_ENUMS) != 0) paths.add(path);
+								break;
+							case IConstants.AccInterface:
+								if ((acceptFlags & ACCEPT_INTERFACES) != 0) paths.add(path);
+								break;
+							default:
+								if ((acceptFlags & ACCEPT_CLASSES) != 0) paths.add(path);
+								break;
+						}
+					}
 				}
 			};
 
@@ -631,24 +681,35 @@
 					return;
 				String[] pkgName = (String[]) keys[i];
 				if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName)) {
-					IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) this.packageFragments.valueTable[i];
-					for (int j = 0, length2 = roots.length; j < length2; j++) {
-						if (requestor.isCanceled())
-							return;
-						PackageFragmentRoot root = (PackageFragmentRoot) roots[j];
-						requestor.acceptPackageFragment(root.getPackageFragment(pkgName));					
+					Object value = this.packageFragments.valueTable[i];
+					if (value instanceof PackageFragmentRoot) {
+						PackageFragmentRoot root = (PackageFragmentRoot) value;
+						requestor.acceptPackageFragment(root.getPackageFragment(pkgName));				
+					} else {
+						IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+						for (int j = 0, length2 = roots.length; j < length2; j++) {
+							if (requestor.isCanceled())
+								return;
+							PackageFragmentRoot root = (PackageFragmentRoot) roots[j];
+							requestor.acceptPackageFragment(root.getPackageFragment(pkgName));					
+						}
 					}
 				}
 			}
 		} else {
 			String[] splittedName = Util.splitOn('.', name, 0, name.length());
-			IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) this.packageFragments.get(splittedName);
-			if (roots != null) {
-				for (int i = 0, length = roots.length; i < length; i++) {
-					if (requestor.isCanceled())
-						return;
-					PackageFragmentRoot root = (PackageFragmentRoot) roots[i];
-					requestor.acceptPackageFragment(root.getPackageFragment(splittedName));
+			Object value = this.packageFragments.get(splittedName);
+			if (value instanceof PackageFragmentRoot) {
+				requestor.acceptPackageFragment(((PackageFragmentRoot) value).getPackageFragment(splittedName));
+			} else {
+				IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value;
+				if (roots != null) {
+					for (int i = 0, length = roots.length; i < length; i++) {
+						if (requestor.isCanceled())
+							return;
+						PackageFragmentRoot root = (PackageFragmentRoot) roots[i];
+						requestor.acceptPackageFragment(root.getPackageFragment(splittedName));
+					}
 				}
 			}
 		}
@@ -710,46 +771,54 @@
 	 * Performs type search in a binary package.
 	 */
 	protected void seekTypesInBinaryPackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) {
-		IClassFile[] classFiles= null;
+		long start = -1;
+		if (VERBOSE)
+			start = System.currentTimeMillis();
 		try {
-			classFiles= pkg.getClassFiles();
-		} catch (JavaModelException npe) {
-			return; // the package is not present
-		}
-		int length= classFiles.length;
-
-		String unqualifiedName= name;
-		int index= name.lastIndexOf('$');
-		if (index != -1) {
-			//the type name of the inner type
-			unqualifiedName= Util.localTypeName(name, index, name.length());
-			// unqualifiedName is empty if the name ends with a '$' sign.
-			// See http://dev.eclipse.org/bugs/show_bug.cgi?id=14642
-		}
-		String matchName= partialMatch ? name.toLowerCase() : name;
-		for (int i= 0; i < length; i++) {
-			if (requestor.isCanceled())
-				return;
-			IClassFile classFile= classFiles[i];
-			String elementName = classFile.getElementName();
-			if (partialMatch) elementName = elementName.toLowerCase();
-
-			/**
-			 * Must use startWith because matchName will never have the 
-			 * extension ".class" and the elementName always will.
-			 */
-			if (elementName.startsWith(matchName)) {
-				IType type= null;
-				try {
-					type= classFile.getType();
-				} catch (JavaModelException npe) {
-					continue; // the classFile is not present
-				}
-				if (!partialMatch || (type.getElementName().length() > 0 && !Character.isDigit(type.getElementName().charAt(0)))) { //not an anonymous type
-					if (nameMatches(unqualifiedName, type, partialMatch) && acceptType(type, acceptFlags, false/*not a source type*/))
-						requestor.acceptType(type);
+			IClassFile[] classFiles= null;
+			try {
+				classFiles= pkg.getClassFiles();
+			} catch (JavaModelException npe) {
+				return; // the package is not present
+			}
+			int length= classFiles.length;
+	
+			String unqualifiedName= name;
+			int index= name.lastIndexOf('$');
+			if (index != -1) {
+				//the type name of the inner type
+				unqualifiedName= Util.localTypeName(name, index, name.length());
+				// unqualifiedName is empty if the name ends with a '$' sign.
+				// See http://dev.eclipse.org/bugs/show_bug.cgi?id=14642
+			}
+			String matchName= partialMatch ? name.toLowerCase() : name;
+			for (int i= 0; i < length; i++) {
+				if (requestor.isCanceled())
+					return;
+				IClassFile classFile= classFiles[i];
+				String elementName = classFile.getElementName();
+				if (partialMatch) elementName = elementName.toLowerCase();
+	
+				/**
+				 * Must use startWith because matchName will never have the 
+				 * extension ".class" and the elementName always will.
+				 */
+				if (elementName.startsWith(matchName)) {
+					IType type= null;
+					try {
+						type= classFile.getType();
+					} catch (JavaModelException npe) {
+						continue; // the classFile is not present
+					}
+					if (!partialMatch || (type.getElementName().length() > 0 && !Character.isDigit(type.getElementName().charAt(0)))) { //not an anonymous type
+						if (nameMatches(unqualifiedName, type, partialMatch) && acceptType(type, acceptFlags, false/*not a source type*/))
+							requestor.acceptType(type);
+					}
 				}
 			}
+		} finally {
+			if (VERBOSE)
+				this.timeSpentInSeekTypesInBinaryPackage += System.currentTimeMillis()-start;
 		}
 	}
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
index 330c57f..f7a44dd 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NamedMember.java
@@ -1,22 +1,27 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.ITypeParameter;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
-import org.eclipse.jdt.core.compiler.CharOperation;
 
 public abstract class NamedMember extends Member {
 
@@ -58,18 +63,111 @@
 	public String getElementName() {
 		return this.name;
 	}
+	
+	protected String getKey(IField field, boolean withAccessFlags, boolean forceOpen) throws JavaModelException {
+		StringBuffer key = new StringBuffer();
+		
+		// declaring class 
+		String declaringKey = getKey((IType) field.getParent(), false/*without access flags*/, forceOpen);
+		key.append(declaringKey);
+		
+		// field name
+		key.append('.');
+		key.append(field.getElementName());
+		
+		// flags
+		if (withAccessFlags) {
+			key.append('^');
+			if (forceOpen) 
+				key.append(field.getFlags());
+			else
+				key.append(Flags.AccDefault);
+		}
+
+		return key.toString();
+	}
+	
+	protected String getKey(IMethod method, boolean withAccessFlags, boolean forceOpen) throws JavaModelException {
+		StringBuffer key = new StringBuffer();
+		
+		// declaring class 
+		String declaringKey = getKey((IType) method.getParent(), false/*without access flags*/, forceOpen);
+		key.append(declaringKey);
+		
+		// selector
+		key.append('.');
+		String selector = method.getElementName();
+		key.append(selector);
+		
+		// parameters
+		key.append('(');
+		String[] parameters = method.getParameterTypes();
+		for (int i = 0, length = parameters.length; i < length; i++)
+			key.append(parameters[i].replace('.', '/'));
+		key.append(')');
+		
+		// return type
+		if (forceOpen)
+			key.append(method.getReturnType());
+		else
+			key.append('V');
+		
+		// flags
+		if (withAccessFlags) {
+			key.append('^');
+			if (forceOpen)
+				key.append(method.getFlags());
+			else
+				key.append(Flags.AccDefault); // cannot get the flags without opening the element		
+		}
+		
+		return key.toString();
+	}
+	
+	protected String getKey(IType type, boolean withAccessFlags, boolean forceOpen) throws JavaModelException {
+		StringBuffer key = new StringBuffer();
+		key.append('L');
+		String packageName = type.getPackageFragment().getElementName();
+		key.append(packageName.replace('.', '/'));
+		if (packageName.length() > 0)
+			key.append('/');
+		String typeQualifiedName = type.getTypeQualifiedName('$');
+		ICompilationUnit cu = (ICompilationUnit) type.getAncestor(IJavaElement.COMPILATION_UNIT);
+		if (cu != null) {
+			String cuName = cu.getElementName();
+			String mainTypeName = cuName.substring(0, cuName.lastIndexOf('.'));
+			int end = typeQualifiedName.indexOf('$');
+			if (end == -1)
+				end = typeQualifiedName.length();
+			String topLevelTypeName = typeQualifiedName.substring(0, end);
+			if (!mainTypeName.equals(topLevelTypeName)) {
+				key.append(mainTypeName);
+				key.append('~');
+			}
+		}
+		key.append(typeQualifiedName);
+		key.append(';');
+		if (withAccessFlags) {
+			key.append('^');
+			if (forceOpen)
+				key.append(type.getFlags());
+			else
+				key.append(Flags.AccDefault);
+		}
+		return key.toString();
+	}
 
 	protected String getFullyQualifiedParameterizedName(String fullyQualifiedName, String uniqueKey) throws JavaModelException {
-		char[][] typeArguments = Signature.getTypeArguments(uniqueKey.toCharArray());
+		String[] typeArguments = new BindingKey(uniqueKey).getTypeArguments();
 		int length = typeArguments.length;
 		if (length == 0) return fullyQualifiedName;
 		StringBuffer buffer = new StringBuffer();
 		buffer.append(fullyQualifiedName);
 		buffer.append('<');
 		for (int i = 0; i < length; i++) {
-			char[] typeArgument = typeArguments[i];
-			CharOperation.replace(typeArgument, '/', '.');
-			buffer.append(Signature.toCharArray(typeArgument));
+			String typeArgument = typeArguments[i];
+			typeArgument.replace('/', '.');
+			buffer.append(Signature.toString(typeArgument));
 			if (i < length-1)
 				buffer.append(',');
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java
index bc1be95..15cbcd5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Openable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,6 +21,7 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.PerformanceStats;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.internal.codeassist.CompletionEngine;
 import org.eclipse.jdt.internal.codeassist.SelectionEngine;
@@ -101,6 +102,14 @@
 	if (requestor == null) {
 		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
 	}
+	PerformanceStats stats = null;
+	if(CompletionEngine.PERF) {
+		stats = PerformanceStats.getStats(JavaModelManager.COMPLETION_PERF, this);
+		stats.startRun(
+				new String(cu.getFileName()) +
+				" at " + //$NON-NLS-1$
+				position);
+	}
 	IBuffer buffer = getBuffer();
 	if (buffer == null) {
 		return;
@@ -117,11 +126,27 @@
 	// code complete
 	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project);
 	engine.complete(cu, position, 0);
-	if (NameLookup.VERBOSE)
+	if(CompletionEngine.PERF) {
+		stats.endRun();
+	}
+	if (NameLookup.VERBOSE) {
 		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
 }
 protected IJavaElement[] codeSelect(org.eclipse.jdt.internal.compiler.env.ICompilationUnit cu, int offset, int length, WorkingCopyOwner owner) throws JavaModelException {
-
+	PerformanceStats stats = null;
+	if(SelectionEngine.PERF) {
+		stats = PerformanceStats.getStats(JavaModelManager.SELECTION_PERF, this);
+		stats.startRun(
+				new String(cu.getFileName()) +
+				" at [" + //$NON-NLS-1$
+				offset +
+				"," + //$NON-NLS-1$
+				length +
+				"]"); //$NON-NLS-1$
+	}
+	
 	JavaProject project = (JavaProject)getJavaProject();
 	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
 	
@@ -138,8 +163,13 @@
 	// fix for 1FVXGDK
 	SelectionEngine engine = new SelectionEngine(environment, requestor, project.getOptions(true));
 	engine.select(cu, offset, offset + length - 1);
-	if (NameLookup.VERBOSE)
+	if(SelectionEngine.PERF) {
+		stats.endRun();
+	}
+	if (NameLookup.VERBOSE) {
 		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
 	return requestor.getElements();
 }
 /*
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java
index 3407f25..ded5721 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OpenableElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java
index 135d3ad..4e91f55 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/OverflowingLRUCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,7 @@
 import java.util.Iterator;
 
 import org.eclipse.jdt.internal.core.util.LRUCache;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  *	The <code>OverflowingLRUCache</code> is an LRUCache which attempts
@@ -387,7 +387,7 @@
 	if(newLoadFactor <= 1.0 && newLoadFactor > 0.0)
 		fLoadFactor = newLoadFactor;
 	else
-		throw new IllegalArgumentException(Util.bind("cache.invalidLoadFactor")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.cache_invalidLoadFactor); 
 }
 	/**
 	 * Sets the maximum amount of space that the cache can store
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
index 18bd545..1172955 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageDeclaration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.IPackageDeclaration;
-import org.eclipse.jdt.core.jdom.*;
 
 /**
  * @see IPackageDeclaration
@@ -30,14 +29,6 @@
 	if (!(o instanceof PackageDeclaration)) return false;
 	return super.equals(o);
 }
-/**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	return (node.getNodeType() == IDOMNode.PACKAGE) && getElementName().equals(node.getName());
-}
 public String getElementName() {
 	return this.name;
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
index 9c9c78a..62ad20b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -30,6 +30,7 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -112,7 +113,7 @@
  */
 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (container == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullContainer); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] containers= new IJavaElement[] {container};
@@ -161,7 +162,7 @@
  */
 public IClassFile getClassFile(String classFileName) {
 	if (!org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(classFileName)) {
-		throw new IllegalArgumentException(Util.bind("element.invalidClassFileName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_invalidClassFileName); 
 	}
 	return new ClassFile(this, classFileName);
 }
@@ -188,7 +189,7 @@
  */
 public ICompilationUnit getCompilationUnit(String cuName) {
 	if (!org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(cuName)) {
-		throw new IllegalArgumentException(Util.bind("convention.unit.notJavaName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.convention_unit_notJavaName); 
 	}
 	return new CompilationUnit(this, cuName, DefaultWorkingCopyOwner.PRIMARY);
 }
@@ -377,7 +378,7 @@
  */
 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (container == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullContainer); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] containers= new IJavaElement[] {container};
@@ -396,7 +397,7 @@
  */
 public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (newName == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullName); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] dests= new IJavaElement[] {this.getParent()};
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java
index 0858cde..14704a4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 58ea7b6..e9dda69 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -68,7 +69,7 @@
 	try {
 		verifyAttachSource(sourcePath);
 		if (monitor != null) {
-			monitor.beginTask(Util.bind("element.attachingSource"), 2); //$NON-NLS-1$
+			monitor.beginTask(Messages.element_attachingSource, 2); 
 		}
 		SourceMapper oldMapper= getSourceMapper();
 		IWorkspace workspace = ResourcesPlugin.getWorkspace();
@@ -318,7 +319,7 @@
  * 		not exist.
  */
 protected int determineKind(IResource underlyingResource) throws JavaModelException {
-	IClasspathEntry[] entries= ((JavaProject)getJavaProject()).getExpandedClasspath(true);
+	IClasspathEntry[] entries= ((JavaProject)getJavaProject()).getResolvedClasspath(true);
 	for (int i= 0; i < entries.length; i++) {
 		IClasspathEntry entry= entries[i];
 		if (entry.getPath().equals(underlyingResource.getFullPath())) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
index f110a9d..caa9645 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryField.java
deleted file mode 100644
index b7fd630..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryField.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-/**
- * Handle representing a binary field that is parameterized.
- * The uniqueKey contains the genericSignature of the parameterized field.
- */
-public class ParameterizedBinaryField extends BinaryField {
-	
-	public String uniqueKey;
-	
-	/*
-	 * See class comments.
-	 */
-	public ParameterizedBinaryField(JavaElement parent, String name, String uniqueKey) {
-		super(parent, name);
-		this.uniqueKey = uniqueKey;
-	}
-
-	/**
-	 * @private Debugging purposes
-	 */
-	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
-		super.toStringInfo(tab, buffer, info);
-		buffer.append(" key="); //$NON-NLS-1$
-		buffer.append(uniqueKey);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryMethod.java
deleted file mode 100644
index 835116a..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryMethod.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-/**
- * Handle representing a binary method that is parameterized.
- * The uniqueKey contains the genericSignature of the parameterized method.
- */
-public class ParameterizedBinaryMethod extends BinaryMethod {
-	
-	public String uniqueKey;
-	
-	/*
-	 * See class comments.
-	 */
-	public ParameterizedBinaryMethod(JavaElement parent, String name, String[] parameterTypes, String uniqueKey) {
-		super(parent, name, parameterTypes);
-		this.uniqueKey = uniqueKey;
-	}
-
-	/**
-	 * @private Debugging purposes
-	 */
-	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
-		super.toStringInfo(tab, buffer, info);
-		buffer.append(" key="); //$NON-NLS-1$
-		buffer.append(uniqueKey);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryType.java
deleted file mode 100644
index c4352ef..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedBinaryType.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-import org.eclipse.jdt.core.JavaModelException;
-
-/**
- * Handle representing a binary type that is parameterized.
- * The uniqueKey contains the genericTypeSignature of the parameterized type.
- */
-public class ParameterizedBinaryType extends BinaryType {
-	
-	public String uniqueKey;
-	
-	/*
-	 * See class comments.
-	 */
-	public ParameterizedBinaryType(JavaElement parent, String name, String uniqueKey) {
-		super(parent, name);
-		this.uniqueKey = uniqueKey;
-	}
-
-	public String getFullyQualifiedParameterizedName() throws JavaModelException {
-		return getFullyQualifiedParameterizedName(getFullyQualifiedName(), this.uniqueKey);
-	}
-	
-	/**
-	 * @private Debugging purposes
-	 */
-	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
-		super.toStringInfo(tab, buffer, info);
-		buffer.append(" key="); //$NON-NLS-1$
-		buffer.append(uniqueKey);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceField.java
deleted file mode 100644
index 593ac98..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceField.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-/**
- * Handle representing a source field that is parameterized.
- * The uniqueKey contains the genericSignature of the parameterized field.
- */
-public class ParameterizedSourceField extends SourceField {
-	
-	public String uniqueKey;
-	
-	/*
-	 * See class comments.
-	 */
-	public ParameterizedSourceField(JavaElement parent, String name, String uniqueKey) {
-		super(parent, name);
-		this.uniqueKey = uniqueKey;
-	}
-	
-	/**
-	 * @private Debugging purposes
-	 */
-	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
-		super.toStringInfo(tab, buffer, info);
-		buffer.append(" key="); //$NON-NLS-1$
-		buffer.append(uniqueKey);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceMethod.java
deleted file mode 100644
index 6ee2145..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceMethod.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-/**
- * Handle representing a source method that is parameterized.
- * The uniqueKey contains the genericSignature of the parameterized method.
- */
-public class ParameterizedSourceMethod extends SourceMethod {
-	
-	public String uniqueKey;
-	
-	/*
-	 * See class comments.
-	 */
-	public ParameterizedSourceMethod(JavaElement parent, String name, String[] parameterTypes, String uniqueKey) {
-		super(parent, name, parameterTypes);
-		this.uniqueKey = uniqueKey;
-	}
-
-	/**
-	 * @private Debugging purposes
-	 */
-	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
-		super.toStringInfo(tab, buffer, info);
-		buffer.append(" key="); //$NON-NLS-1$
-		buffer.append(uniqueKey);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceType.java
deleted file mode 100644
index 304f0cf..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ParameterizedSourceType.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-import org.eclipse.jdt.core.JavaModelException;
-
-/**
- * Handle representing a source type that is parameterized.
- * The uniqueKey contains the genericTypeSignature of the parameterized type.
- */
-public class ParameterizedSourceType extends SourceType {
-	
-	public String uniqueKey;
-	
-	/*
-	 * See class comments.
-	 */
-	public ParameterizedSourceType(JavaElement parent, String name, String uniqueKey) {
-		super(parent, name);
-		this.uniqueKey = uniqueKey;
-	}
-	
-	public String getFullyQualifiedParameterizedName() throws JavaModelException {
-		return getFullyQualifiedParameterizedName(getFullyQualifiedName(), this.uniqueKey);
-	}
-	
-	/**
-	 * @private Debugging purposes
-	 */
-	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
-		super.toStringInfo(tab, buffer, info);
-		buffer.append(" key="); //$NON-NLS-1$
-		buffer.append(uniqueKey);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
index fb0ee70..3cec2ff 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,13 +18,14 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * Reconcile a working copy and signal the changes through a delta.
  */
 public class ReconcileWorkingCopyOperation extends JavaModelOperation {
-		
+	public static boolean PERF = false;
+	
 	boolean createAST;
 	int astLevel;
 	boolean forceProblemDetection;
@@ -46,7 +47,7 @@
 		if (this.progressMonitor != null){
 			if (this.progressMonitor.isCanceled()) 
 				throw new OperationCanceledException();
-			this.progressMonitor.beginTask(Util.bind("element.reconciling"), 2); //$NON-NLS-1$
+			this.progressMonitor.beginTask(Messages.element_reconciling, 2); 
 		}
 	
 		CompilationUnit workingCopy = getWorkingCopy();
@@ -75,12 +76,12 @@
 					    try {
 							problemRequestor.beginReporting();
 							char[] contents = workingCopy.getContents();
-							unit = CompilationUnitProblemFinder.process(workingCopy, contents, this.workingCopyOwner, problemRequestor, false/*don't cleanup cu*/, this.progressMonitor);
+							unit = CompilationUnitProblemFinder.process(workingCopy, contents, this.workingCopyOwner, problemRequestor, !this.createAST/*reset env if not creating AST*/, this.progressMonitor);
 							problemRequestor.endReporting();
 							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, true/*isResolved*/, workingCopy.owner, this.progressMonitor);
+								this.ast = AST.convertCompilationUnit(this.astLevel, unit, contents, options, true/*isResolved*/, workingCopy, this.progressMonitor);
 								if (progressMonitor != null) progressMonitor.worked(1);
 							}
 					    } finally {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java
index fde2ce0..4bb5ece 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Region.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java
index feef114..352fe23 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameElementsOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,7 @@
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.ISourceReference;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * This operation renames elements.
@@ -42,7 +42,7 @@
  * @see MultiOperation
  */
 protected String getMainTaskName() {
-	return Util.bind("operation.renameElementProgress"); //$NON-NLS-1$
+	return Messages.operation_renameElementProgress; 
 }
 /**
  * @see CopyElementsOperation#isRename()
@@ -79,12 +79,6 @@
 	if (elementType < IJavaElement.TYPE || elementType == IJavaElement.INITIALIZER)
 		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
 		
-	Member localContext;
-	if (element instanceof Member && (localContext = ((Member)element).getOuterMostLocalContext()) != null && localContext != element) {
-		// JDOM doesn't support source manipulation in local/anonymous types
-		error(IJavaModelStatusConstants.INVALID_ELEMENT_TYPES, element);
-	}
-
 	verifyRenaming(element);
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java
index 2715054..1879091 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/RenameResourceElementsOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,7 +13,7 @@
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * This operation renames resources (Package fragments and compilation units).
@@ -38,7 +38,7 @@
  * @see MultiOperation
  */
 protected String getMainTaskName() {
-	return Util.bind("operation.renameResourceProgress"); //$NON-NLS-1$
+	return Messages.operation_renameResourceProgress; 
 }
 /**
  * @see CopyResourceElementsOperation#isRename()
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
new file mode 100644
index 0000000..fb01686
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryField.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a binary field that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved field. Use BindingKey to decode it.
+ */
+public class ResolvedBinaryField extends BinaryField {
+	
+	private String uniqueKey;
+	
+	/*
+	 * See class comments.
+	 */
+	public ResolvedBinaryField(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryField#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IField#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+		super.toStringInfo(tab, buffer, info);
+		buffer.append(" {key="); //$NON-NLS-1$
+		buffer.append(this.uniqueKey);
+		buffer.append("}"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
new file mode 100644
index 0000000..3014dc9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryMethod.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a binary method that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved method. Use BindingKey to decode it.
+ */
+public class ResolvedBinaryMethod extends BinaryMethod {
+	
+	private String uniqueKey;
+	
+	/*
+	 * See class comments.
+	 */
+	public ResolvedBinaryMethod(JavaElement parent, String name, String[] parameterTypes, String uniqueKey) {
+		super(parent, name, parameterTypes);
+		this.uniqueKey = uniqueKey;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryMethod#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IMethod#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+		super.toStringInfo(tab, buffer, info);
+		buffer.append(" {key="); //$NON-NLS-1$
+		buffer.append(this.uniqueKey);
+		buffer.append("}"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
new file mode 100644
index 0000000..7f31640
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedBinaryType.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Handle representing a binary type that is resolved.
+ * The uniqueKey contains the genericTypeSignature of the resolved type. Use BindingKey to decode it.
+ */
+public class ResolvedBinaryType extends BinaryType {
+	
+	private String uniqueKey;
+	
+	/*
+	 * See class comments.
+	 */
+	public ResolvedBinaryType(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+
+	public String getFullyQualifiedParameterizedName() throws JavaModelException {
+		return getFullyQualifiedParameterizedName(getFullyQualifiedName(), this.uniqueKey);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryType#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.BinaryType#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+	
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+		super.toStringInfo(tab, buffer, info);
+		buffer.append(" {key="); //$NON-NLS-1$
+		buffer.append(this.uniqueKey);
+		buffer.append("}"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
new file mode 100644
index 0000000..0c027fd
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceField.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a source field that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved field. Use BindingKey to decode it.
+ */
+public class ResolvedSourceField extends SourceField {
+	
+	private String uniqueKey;
+	
+	/*
+	 * See class comments.
+	 */
+	public ResolvedSourceField(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceField#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IField#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+	
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+		super.toStringInfo(tab, buffer, info);
+		buffer.append(" {key="); //$NON-NLS-1$
+		buffer.append(this.uniqueKey);
+		buffer.append("}"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
new file mode 100644
index 0000000..c9d8e45
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceMethod.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+/**
+ * Handle representing a source method that is resolved.
+ * The uniqueKey contains the genericSignature of the resolved method. Use BindingKey to decode it.
+ */
+public class ResolvedSourceMethod extends SourceMethod {
+	
+	private String uniqueKey;
+	
+	/*
+	 * See class comments.
+	 */
+	public ResolvedSourceMethod(JavaElement parent, String name, String[] parameterTypes, String uniqueKey) {
+		super(parent, name, parameterTypes);
+		this.uniqueKey = uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceMethod#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.core.IMethod#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+		super.toStringInfo(tab, buffer, info);
+		buffer.append(" {key="); //$NON-NLS-1$
+		buffer.append(this.uniqueKey);
+		buffer.append("}"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
new file mode 100644
index 0000000..9d2f0a3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ResolvedSourceType.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core;
+
+import org.eclipse.jdt.core.JavaModelException;
+
+/**
+ * Handle representing a source type that is resolved.
+ * The uniqueKey contains the genericTypeSignature of the resolved type. Use BindingKey to decode it.
+ */
+public class ResolvedSourceType extends SourceType {
+	
+	private String uniqueKey;
+	
+	/*
+	 * See class comments.
+	 */
+	public ResolvedSourceType(JavaElement parent, String name, String uniqueKey) {
+		super(parent, name);
+		this.uniqueKey = uniqueKey;
+	}
+	
+	public String getFullyQualifiedParameterizedName() throws JavaModelException {
+		return getFullyQualifiedParameterizedName(getFullyQualifiedName(), this.uniqueKey);
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceType#getKey()
+	 */
+	public String getKey() {
+		return this.uniqueKey;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.core.SourceType#isResolved()
+	 */
+	public boolean isResolved() {
+		return true;
+	}
+	
+	/**
+	 * @private Debugging purposes
+	 */
+	protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
+		super.toStringInfo(tab, buffer, info);
+		buffer.append(" {key="); //$NON-NLS-1$
+		buffer.append(this.uniqueKey);
+		buffer.append("}"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
index 5b80f77..6dab364 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,14 +23,14 @@
 import org.eclipse.jdt.core.search.IJavaSearchScope;
 import org.eclipse.jdt.internal.codeassist.ISearchRequestor;
 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
-import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.env.ISourceType;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
 import org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor;
-import org.eclipse.jdt.internal.core.search.SearchBasicEngine;
 
 /**
  *	This class provides a <code>SearchableBuilderEnvironment</code> for code assist which
@@ -41,6 +41,7 @@
 	
 	public NameLookup nameLookup;
 	protected ICompilationUnit unitToSkip;
+	protected org.eclipse.jdt.core.ICompilationUnit[] workingCopies;
 
 	protected JavaProject project;
 	protected IJavaSearchScope searchScope;
@@ -52,14 +53,17 @@
 	 */
 	public SearchableEnvironment(JavaProject project, org.eclipse.jdt.core.ICompilationUnit[] workingCopies) throws JavaModelException {
 		this.project = project;
-		this.checkAccessRestrictions = !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true));
+		this.checkAccessRestrictions = 
+			!JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+			|| !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true));
+		this.workingCopies = workingCopies;
 		this.nameLookup = project.newNameLookup(workingCopies);
 
 		// Create search scope with visible entry on the project's classpath
 		if(this.checkAccessRestrictions) {
-			this.searchScope = SearchBasicEngine.createJavaSearchScope(new IJavaElement[] {project});
+			this.searchScope = BasicSearchEngine.createJavaSearchScope(new IJavaElement[] {project});
 		} else {
-			this.searchScope = SearchBasicEngine.createJavaSearchScope(this.nameLookup.packageFragmentRoots);
+			this.searchScope = BasicSearchEngine.createJavaSearchScope(this.nameLookup.packageFragmentRoots);
 		}
 	}
 
@@ -67,16 +71,7 @@
 	 * Creates a SearchableEnvironment on the given project
 	 */
 	public SearchableEnvironment(JavaProject project, WorkingCopyOwner owner) throws JavaModelException {
-		this.project = project;
-		this.checkAccessRestrictions = !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true));
-		this.nameLookup = project.newNameLookup(owner);
-
-		// Create search scope with visible entry on the project's classpath
-		if(this.checkAccessRestrictions) {
-			this.searchScope = SearchBasicEngine.createJavaSearchScope(new IJavaElement[] {project});
-		} else {
-			this.searchScope = SearchBasicEngine.createJavaSearchScope(this.nameLookup.packageFragmentRoots);
-		}
+		this(project, owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary WCs*/));
 	}
 
 	/**
@@ -102,12 +97,12 @@
 				PackageFragmentRoot root = (PackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
 				ClasspathEntry entry = (ClasspathEntry) this.nameLookup.rootToResolvedEntries.get(root);
 				if (entry != null) { // reverse map always contains resolved CP entry
-					accessRestriction = entry.getImportRestriction();
-					if (accessRestriction != null) {
+					AccessRuleSet accessRuleSet = entry.getAccessRuleSet();
+					if (accessRuleSet != null) {
 						// TODO (philippe) improve char[] <-> String conversions to avoid performing them on the fly
 						char[][] packageChars = CharOperation.splitOn('.', packageName.toCharArray());
-						char[] typeChars = typeName.toCharArray();
-						accessRestriction = accessRestriction.getViolatedRestriction(CharOperation.concatWith(packageChars, typeChars, '/'), null);
+						char[] classFileChars = type.getParent().getElementName().toCharArray();
+						accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, classFileChars, '/'));
 					}
 				}
 			}
@@ -130,7 +125,7 @@
 					// find all siblings (other types declared in same unit, since may be used for name resolution)
 					IType[] types = sourceType.getHandle().getCompilationUnit().getTypes();
 					ISourceType[] sourceTypes = new ISourceType[types.length];
-
+	
 					// in the resulting collection, ensure the requested type is the first one
 					sourceTypes[0] = sourceType;
 					int length = types.length;
@@ -273,57 +268,16 @@
 				}
 			};
 			IRestrictedAccessTypeRequestor typeRequestor = new IRestrictedAccessTypeRequestor() {
-				public void acceptAnnotation(
-					char[] packageName,
-					char[] simpleTypeName,
-					char[][] enclosingTypeNames,
-					String path,
-					AccessRestriction access) {
+				public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
 					if (excludePath != null && excludePath.equals(path))
 						return;
 					if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
 						return; // accept only top level types
-					storage.acceptAnnotation(packageName, simpleTypeName, IConstants.AccPublic, access);
-				}
-				public void acceptClass(
-					char[] packageName,
-					char[] simpleTypeName,
-					char[][] enclosingTypeNames,
-					String path,
-					AccessRestriction access) {
-					if (excludePath != null && excludePath.equals(path))
-						return;
-					if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
-						return; // accept only top level types
-					storage.acceptClass(packageName, simpleTypeName, IConstants.AccPublic, access);
-				}
-				public void acceptEnum(
-					char[] packageName,
-					char[] simpleTypeName,
-					char[][] enclosingTypeNames,
-					String path,
-					AccessRestriction access) {
-					if (excludePath != null && excludePath.equals(path))
-						return;
-					if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
-						return; // accept only top level types
-					storage.acceptEnum(packageName, simpleTypeName, IConstants.AccPublic, access);
-				}
-				public void acceptInterface(
-					char[] packageName,
-					char[] simpleTypeName,
-					char[][] enclosingTypeNames,
-					String path,
-					AccessRestriction access) {
-					if (excludePath != null && excludePath.equals(path))
-						return;
-					if (enclosingTypeNames != null && enclosingTypeNames.length > 0)
-						return; // accept only top level types
-					storage.acceptInterface(packageName, simpleTypeName, IConstants.AccPublic, access);
+					storage.acceptType(packageName, simpleTypeName, modifiers, access);
 				}
 			};
 			try {
-				new SearchBasicEngine().searchAllTypeNames(
+				new BasicSearchEngine(this.workingCopies).searchAllTypeNames(
 					qualification,
 					simpleName,
 					SearchPattern.R_PREFIX_MATCH, // not case sensitive
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
index f921993..0346a12 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironmentRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,8 +19,9 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.codeassist.ISearchRequestor;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
 
 /**
  * Implements <code>IJavaElementRequestor</code>, wrappering and forwarding
@@ -65,7 +66,9 @@
 	this.unitToSkip= unitToSkip;
 	this.project= project;
 	this.nameLookup = nameLookup;
-	this.checkAccessRestrictions = !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true));
+	this.checkAccessRestrictions = 
+		!JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+		|| !JavaCore.IGNORE.equals(project.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true));
 }
 /**
  * Do nothing, a SearchRequestor does not accept initializers
@@ -90,8 +93,7 @@
 		if (this.unitToSkip != null && this.unitToSkip.equals(type.getCompilationUnit())){
 			return;
 		}
-		String packageName = type.getPackageFragment().getElementName();
-		String typeName = type.getElementName();
+		char[] packageName = type.getPackageFragment().getElementName().toCharArray();
 		boolean isBinary = type instanceof BinaryType;
 		
 		// determine associated access restriction
@@ -101,20 +103,16 @@
 			PackageFragmentRoot root = (PackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
 			ClasspathEntry entry = (ClasspathEntry) this.nameLookup.rootToResolvedEntries.get(root);
 			if (entry != null) { // reverse map always contains resolved CP entry
-				accessRestriction = entry.getImportRestriction();
-				if (accessRestriction != null) {
+				AccessRuleSet accessRuleSet = entry.getAccessRuleSet();
+				if (accessRuleSet != null) {
 					// TODO (philippe) improve char[] <-> String conversions to avoid performing them on the fly
-					char[][] packageChars = CharOperation.splitOn('.', packageName.toCharArray());
-					char[] typeChars = typeName.toCharArray();
-					accessRestriction = accessRestriction.getViolatedRestriction(CharOperation.concatWith(packageChars, typeChars, '/'), null);
+					char[][] packageChars = CharOperation.splitOn('.', packageName);
+					char[] fileChars = type.getParent().getElementName().toCharArray();
+					accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, fileChars, '/'));
 				}
 			}
 		}
-		if (type.isClass()) {
-			this.requestor.acceptClass(type.getPackageFragment().getElementName().toCharArray(), type.getElementName().toCharArray(), type.getFlags(), accessRestriction);
-		} else {
-			this.requestor.acceptInterface(type.getPackageFragment().getElementName().toCharArray(), type.getElementName().toCharArray(), type.getFlags(), accessRestriction);
-		}
+		this.requestor.acceptType(packageName, type.getElementName().toCharArray(), type.getFlags(), accessRestriction);
 	} catch (JavaModelException jme) {
 		// ignore
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
index a932791..bc53cd2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -28,12 +28,11 @@
 import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
 import org.eclipse.jdt.internal.codeassist.SelectionEngine;
 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding;
-import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
@@ -79,16 +78,15 @@
  *
  * fix for 1FWFT6Q
  */
-protected void acceptBinaryMethod(IType type, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] paramterSignatures, char[] uniqueKey) {
-	IMethod method= type.getMethod(new String(selector), paramterSignatures);
+protected void acceptBinaryMethod(IType type, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, char[] uniqueKey) {
+	IMethod method= type.getMethod(new String(selector), parameterSignatures);
 	if (method.exists()) {
-		if(uniqueKey != null) {
-			method = new ParameterizedBinaryMethod(
+		if (uniqueKey != null)
+			method = new ResolvedBinaryMethod(
 					(JavaElement)method.getParent(),
 					method.getElementName(),
 					method.getParameterTypes(),
 					new String(uniqueKey));
-		}
 		addElement(method);
 		if(SelectionEngine.DEBUG){
 			System.out.print("SELECTION - accept method("); //$NON-NLS-1$
@@ -98,22 +96,49 @@
 	}
 }
 /**
- * Resolve the annotation.
+ * Resolve the type.
  */
-public void acceptAnnotation(char[] packageName, char[] annotationName, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-	acceptType(packageName, annotationName, NameLookup.ACCEPT_ANNOTATIONS, isDeclaration, genericTypeSignature, start, end);
-}
-/**
- * Resolve the class.
- */
-public void acceptClass(char[] packageName, char[] className, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-	acceptType(packageName, className, NameLookup.ACCEPT_CLASSES, isDeclaration, genericTypeSignature, start, end);
-}
-/**
- * Resolve the enum.
- */
-public void acceptEnum(char[] packageName, char[] enumName, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-	acceptType(packageName, enumName, NameLookup.ACCEPT_ENUMS, isDeclaration, genericTypeSignature, start, end);
+public void acceptType(char[] packageName, char[] typeName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+	int acceptFlags = 0;
+	int kind = modifiers & (IConstants.AccInterface+IConstants.AccEnum+IConstants.AccAnnotation);
+	switch (kind) {
+		case IConstants.AccAnnotation:
+		case IConstants.AccAnnotation+IConstants.AccInterface:
+			acceptFlags = NameLookup.ACCEPT_ANNOTATIONS;
+			break;
+		case IConstants.AccEnum:
+			acceptFlags = NameLookup.ACCEPT_ENUMS;
+			break;
+		case IConstants.AccInterface:
+			acceptFlags = NameLookup.ACCEPT_INTERFACES;
+			break;
+		default:
+			acceptFlags = NameLookup.ACCEPT_CLASSES;
+			break;
+	}
+	IType type = null;
+	if(isDeclaration) {
+		type = resolveTypeByLocation(packageName, typeName, acceptFlags, start, end);
+	} else {
+		type = resolveType(packageName, typeName, acceptFlags);
+		if(type != null ) {
+			String key = uniqueKey == null ? type.getKey() : new String(uniqueKey);
+			if(type.isBinary()) {
+				type = new ResolvedBinaryType((JavaElement)type.getParent(), type.getElementName(), key);
+			} else {
+				type = new ResolvedSourceType((JavaElement)type.getParent(), type.getElementName(), key);
+			}
+		}
+	}
+	
+	if (type != null) {
+		addElement(type);
+		if(SelectionEngine.DEBUG){
+			System.out.print("SELECTION - accept type("); //$NON-NLS-1$
+			System.out.print(type.toString());
+			System.out.println(")"); //$NON-NLS-1$
+		}
+	} 
 }
 /**
  * @see ISelectionRequestor#acceptError
@@ -156,14 +181,14 @@
 		if (type != null) {
 			IField field= type.getField(new String(name));
 			if (field.exists()) {
-				if(uniqueKey != null) {
+				if (uniqueKey != null) {
 					if(field.isBinary()) {
-						field = new ParameterizedBinaryField(
+						field = new ResolvedBinaryField(
 								(JavaElement)field.getParent(),
 								field.getElementName(),
 								new String(uniqueKey));
 					} else {
-						field = new ParameterizedSourceField(
+						field = new ResolvedSourceField(
 								(JavaElement)field.getParent(),
 								field.getElementName(),
 								new String(uniqueKey));
@@ -179,12 +204,6 @@
 		}
 	}
 }
-/**
- * Resolve the interface
- */
-public void acceptInterface(char[] packageName, char[] interfaceName, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-	acceptType(packageName, interfaceName, NameLookup.ACCEPT_INTERFACES, isDeclaration, genericTypeSignature, start, end);
-}
 public void acceptLocalField(FieldBinding fieldBinding) {
 	IJavaElement res;
 	if(fieldBinding.declaringClass instanceof ParameterizedTypeBinding) {
@@ -198,18 +217,17 @@
 		IType type = (IType) res;
 		IField field= type.getField(new String(fieldBinding.name));
 		if (field.exists()) {
-			if (fieldBinding instanceof ParameterizedFieldBinding) {
-				if(field.isBinary()) {
-					field = new ParameterizedBinaryField(
-							(JavaElement)field.getParent(),
-							field.getElementName(),
-							new String(fieldBinding.computeUniqueKey()));
-				} else {
-					field = new ParameterizedSourceField(
-							(JavaElement)field.getParent(),
-							field.getElementName(),
-							new String(fieldBinding.computeUniqueKey()));
-				}
+			char[] uniqueKey = fieldBinding.computeUniqueKey();
+			if(field.isBinary()) {
+				field = new ResolvedBinaryField(
+						(JavaElement)field.getParent(),
+						field.getElementName(),
+						new String(uniqueKey));
+			} else {
+				field = new ResolvedSourceField(
+						(JavaElement)field.getParent(),
+						field.getElementName(),
+						new String(uniqueKey));
 			}
 			addElement(field);
 			if(SelectionEngine.DEBUG){
@@ -223,18 +241,21 @@
 public void acceptLocalMethod(MethodBinding methodBinding) {
 	IJavaElement res = findLocalElement(methodBinding.sourceStart());
 	if(res != null && res.getElementType() == IJavaElement.METHOD) {
-		if (methodBinding instanceof ParameterizedMethodBinding) {
-			if(((IMethod)res).isBinary()) {
-				res = new ParameterizedBinaryField(
-						(JavaElement)res.getParent(),
-						res.getElementName(),
-						new String(methodBinding.computeUniqueKey()));
-			} else {
-				res = new ParameterizedSourceField(
-						(JavaElement)res.getParent(),
-						res.getElementName(),
-						new String(methodBinding.computeUniqueKey()));
-			}
+		IMethod method = (IMethod) res;
+		
+		char[] uniqueKey = methodBinding.computeUniqueKey();
+		if(method.isBinary()) {
+			res = new ResolvedBinaryMethod(
+					(JavaElement)res.getParent(),
+					method.getElementName(),
+					method.getParameterTypes(), 
+					new String(uniqueKey));
+		} else {
+			res = new ResolvedSourceMethod(
+					(JavaElement)res.getParent(),
+					method.getElementName(),
+					method.getParameterTypes(), 
+					new String(uniqueKey));
 		}
 		addElement(res);
 		if(SelectionEngine.DEBUG){
@@ -249,13 +270,11 @@
 	if(typeBinding instanceof ParameterizedTypeBinding) {
 		LocalTypeBinding localTypeBinding = (LocalTypeBinding)((ParameterizedTypeBinding)typeBinding).type;
 		res = findLocalElement(localTypeBinding.sourceStart());
-		if(typeBinding.isParameterizedType()) {
-			res = new ParameterizedSourceType((JavaElement)res.getParent(), res.getElementName(), new String(typeBinding.computeUniqueKey()));
-		}
 	} else if(typeBinding instanceof SourceTypeBinding) {
 		res = findLocalElement(((SourceTypeBinding)typeBinding).sourceStart());
 	}
 	if(res != null && res.getElementType() == IJavaElement.TYPE) {
+		res = new ResolvedSourceType((JavaElement)res.getParent(), res.getElementName(), new String(typeBinding.computeUniqueKey()));
 		addElement(res);
 		if(SelectionEngine.DEBUG){
 			System.out.print("SELECTION - accept type("); //$NON-NLS-1$
@@ -291,6 +310,11 @@
  * Resolve the method
  */
 public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, String enclosingDeclaringTypeSignature, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, String[] parameterSignatures, boolean isConstructor, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+	IJavaElement[] previousElement = this.elements;
+	int previousElementIndex = this.elementIndex;
+	this.elements = JavaElement.NO_ELEMENTS;
+	this.elementIndex = -1;
+	
 	if(isDeclaration) {
 		IType type = resolveTypeByLocation(declaringTypePackageName, declaringTypeName,
 				NameLookup.ACCEPT_ALL,
@@ -333,6 +357,15 @@
 			}
 		}
 	}
+	
+	if(previousElementIndex > -1) {
+		int elementsLength = this.elementIndex + previousElementIndex + 2;
+		if(elementsLength > this.elements.length) {
+			System.arraycopy(this.elements, 0, this.elements = new IJavaElement[elementsLength * 2 + 1], 0, this.elementIndex + 1);
+		}
+		System.arraycopy(previousElement, 0, this.elements, this.elementIndex + 1, previousElementIndex + 1);
+		this.elementIndex += previousElementIndex + 1;
+	}
 }
 /**
  * Resolve the package
@@ -363,17 +396,14 @@
 		for (int i = 0; i < methods.length; i++) {
 			if (methods[i].getElementName().equals(name)
 					&& methods[i].getParameterTypes().length == parameterTypeNames.length) {
-				if(uniqueKey != null) {
-					IMethod method = methods[i];
-					ParameterizedSourceMethod parameterizedSourceMethod = new ParameterizedSourceMethod(
-							(JavaElement)method.getParent(),
-							method.getElementName(),
-							method.getParameterTypes(),
-							new String(uniqueKey));
-					addElement(parameterizedSourceMethod);
-				} else {
-					addElement(methods[i]);
-				}
+				IMethod method = methods[i];
+				if (uniqueKey != null)
+					method = new ResolvedSourceMethod(
+						(JavaElement)method.getParent(),
+						method.getElementName(),
+						method.getParameterTypes(),
+						new String(uniqueKey));
+				addElement(method);
 			}
 		}
 	} catch (JavaModelException e) {
@@ -412,7 +442,7 @@
 		String[] signatures = method.getParameterTypes();
 		boolean match= true;
 		for (int p = 0; p < signatures.length; p++) {
-			String simpleName= Signature.getSimpleName(Signature.toString(signatures[p]));
+			String simpleName= Signature.getSimpleName(Signature.toString(Signature.getTypeErasure(signatures[p])));
 			char[] simpleParameterName = CharOperation.lastSegment(parameterTypeNames[p], '.');
 			if (!simpleName.equals(new String(simpleParameterName))) {
 				match = false;
@@ -462,33 +492,6 @@
 	}
 	return;
 }
-/**
- * Resolve the type, adding to the resolved elements.
- */
-protected void acceptType(char[] packageName, char[] typeName, int acceptFlags, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-	IType type = null;
-	if(isDeclaration) {
-		type = resolveTypeByLocation(packageName, typeName, acceptFlags, start, end);
-	} else {
-		type = resolveType(packageName, typeName, acceptFlags);
-		if(type != null && genericTypeSignature != null) {
-			if(type.isBinary()) {
-				type = new ParameterizedBinaryType((JavaElement)type.getParent(), type.getElementName(), new String(genericTypeSignature));
-			} else {
-				type = new ParameterizedSourceType((JavaElement)type.getParent(), type.getElementName(), new String(genericTypeSignature));
-			}
-		}
-	}
-	
-	if (type != null) {
-		addElement(type);
-		if(SelectionEngine.DEBUG){
-			System.out.print("SELECTION - accept type("); //$NON-NLS-1$
-			System.out.print(type.toString());
-			System.out.println(")"); //$NON-NLS-1$
-		}
-	} 
-}
 public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) {
 	IType type;
 	if(isDeclaration) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java
index 837d73f..704a8f1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SetClasspathOperation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,9 +32,10 @@
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaModelException;
 
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.util.ObjectVector;
 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -55,11 +56,17 @@
 	JavaProject project;
 	boolean identicalRoots;
 	
-	public static final IClasspathEntry[] REUSE_ENTRIES = new IClasspathEntry[0];
-	public static final IClasspathEntry[] UPDATE_ENTRIES = new IClasspathEntry[0];
-	// if reusing output location, then also reuse clean flag
-	public static final IPath REUSE_PATH = new Path("Reuse Existing Output Location");  //$NON-NLS-1$
-	public static final IPath[] REUSE_PATHS = new IPath[0];
+	/*
+	 * Used to indicate that the classpath entries remain the same.
+	 */
+	public static final IClasspathEntry[] DO_NOT_SET_ENTRIES = new IClasspathEntry[0];
+	
+	public static final IClasspathEntry[] DO_NOT_UPDATE_PROJECT_REFS = new IClasspathEntry[0];
+	
+	/*
+	 * Used to indicate that the output location remains the same.
+	 */
+	public static final IPath DO_NOT_SET_OUTPUT = new Path("Reuse Existing Output Location");  //$NON-NLS-1$
 	
 	/**
 	 * When executed, this operation sets the classpath of the given project.
@@ -109,7 +116,10 @@
 		}
 	}
 
-
+	protected boolean canModifyRoots() {
+		// setting classpath can modify roots
+		return true;
+	}
 
 	/**
 	 * Returns the index of the item in the list if the given list contains the specified entry. If the list does
@@ -251,8 +261,8 @@
 		JavaModelException originalException = null;
 
 		try {
-			if (this.newRawPath == UPDATE_ENTRIES) this.newRawPath = project.getRawClasspath();
-			if (this.newRawPath != REUSE_ENTRIES){
+			if (this.newRawPath == DO_NOT_UPDATE_PROJECT_REFS) this.newRawPath = project.getRawClasspath();
+			if (this.newRawPath != DO_NOT_SET_ENTRIES){
 				updateClasspath();
 				project.updatePackageFragmentRoots();
 				JavaModelManager.getJavaModelManager().getDeltaProcessor().addForRefresh(project);
@@ -265,7 +275,7 @@
 		} finally { // if traversed by an exception we still need to update the output location when necessary
 
 			try {
-				if (this.newOutputLocation != REUSE_PATH) updateOutputLocation();
+				if (this.newOutputLocation != DO_NOT_SET_OUTPUT) updateOutputLocation();
 
 			} catch(JavaModelException e){
 				if (originalException != null) throw originalException; 
@@ -415,14 +425,14 @@
 					ClasspathEntry oldEntry = (ClasspathEntry) oldResolvedPath[i];
 					ClasspathEntry newEntry = (ClasspathEntry) newResolvedPath[index];
 					if (oldEntry.isExported || newEntry.isExported) { // then we need to verify if there's access restriction
-						AccessRestriction oldRestriction = oldEntry.getImportRestriction();
-						AccessRestriction newRestriction = newEntry.getImportRestriction();
+						AccessRuleSet oldRuleSet = oldEntry.getAccessRuleSet();
+						AccessRuleSet newRuleSet = newEntry.getAccessRuleSet();
 						if (index != i) { // entry has been moved
-							needToUpdateDependents |= (oldRestriction != null || newRestriction != null); // there's an access restriction, this may change combination
-						} else if (oldRestriction == null) {
-							needToUpdateDependents |= newRestriction != null; // access restriction was added
+							needToUpdateDependents |= (oldRuleSet != null || newRuleSet != null); // there's an access restriction, this may change combination
+						} else if (oldRuleSet == null) {
+							needToUpdateDependents |= newRuleSet != null; // access restriction was added
 						} else {
-							needToUpdateDependents |= !oldRestriction.equals(newRestriction); // access restriction has changed or has been removed
+							needToUpdateDependents |= !oldRuleSet.equals(newRuleSet); // access restriction has changed or has been removed
 						}
 					}
 					this.needCycleCheck |= (oldEntry.isExported() != newEntry.isExported());
@@ -581,13 +591,13 @@
 		if (!this.canChangeResources || !this.needSave) return;
 				
 		IClasspathEntry[] classpathForSave;
-		if (this.newRawPath == REUSE_ENTRIES || this.newRawPath == UPDATE_ENTRIES){
+		if (this.newRawPath == DO_NOT_SET_ENTRIES || this.newRawPath == DO_NOT_UPDATE_PROJECT_REFS){
 			classpathForSave = project.getRawClasspath();
 		} else {
 			classpathForSave = this.newRawPath;
 		}
 		IPath outputLocationForSave;
-		if (this.newOutputLocation == REUSE_PATH){
+		if (this.newOutputLocation == DO_NOT_SET_OUTPUT){
 			outputLocationForSave = project.getOutputLocation();
 		} else {
 			outputLocationForSave = this.newOutputLocation;
@@ -603,8 +613,8 @@
 		StringBuffer buffer = new StringBuffer(20);
 		buffer.append("SetClasspathOperation\n"); //$NON-NLS-1$
 		buffer.append(" - classpath : "); //$NON-NLS-1$
-		if (this.newRawPath == REUSE_ENTRIES){
-			buffer.append("<Reuse Existing Classpath>"); //$NON-NLS-1$
+		if (this.newRawPath == DO_NOT_SET_ENTRIES){
+			buffer.append("<Reuse Existing Classpath Entries>"); //$NON-NLS-1$
 		} else {
 			buffer.append("{"); //$NON-NLS-1$
 			for (int i = 0; i < this.newRawPath.length; i++) {
@@ -614,7 +624,7 @@
 			}
 		}
 		buffer.append("\n - output location : ");  //$NON-NLS-1$
-		if (this.newOutputLocation == REUSE_PATH){
+		if (this.newOutputLocation == DO_NOT_SET_OUTPUT){
 			buffer.append("<Reuse Existing Output Location>"); //$NON-NLS-1$
 		} else {
 			buffer.append(this.newOutputLocation.toString()); //$NON-NLS-1$
@@ -624,7 +634,7 @@
 
 	private void updateClasspath() throws JavaModelException {
 
-		beginTask(Util.bind("classpath.settingProgress", project.getElementName()), 2); //$NON-NLS-1$
+		beginTask(Messages.bind(Messages.classpath_settingProgress, project.getElementName()), 2); 
 
 		// SIDE-EFFECT: from thereon, the classpath got modified
 		project.getPerProjectInfo().updateClasspathInformation(this.newRawPath);
@@ -662,6 +672,7 @@
 				try {
 					final JavaProject affectedProject = (JavaProject) projects[i];
 					if (affectedProject.equals(initialProject)) continue; // skip itself
+					if (!affectedProject.isOpen()) continue; // skip project as its namelookup caches do not exist
 					
 					// consider ALL dependents (even indirect ones), since they may need to
 					// flush their respective namelookup caches (all pkg fragment roots).
@@ -678,8 +689,8 @@
 									}
 									public void run() throws JavaModelException {
 										affectedProject.setRawClasspath(
-											UPDATE_ENTRIES, 
-											SetClasspathOperation.REUSE_PATH, 
+											DO_NOT_UPDATE_PROJECT_REFS, 
+											SetClasspathOperation.DO_NOT_SET_OUTPUT, 
 											SetClasspathOperation.this.progressMonitor, 
 											SetClasspathOperation.this.canChangeResources,  
 											affectedProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/), 
@@ -733,7 +744,7 @@
 	 */
 	protected void updateOutputLocation() throws JavaModelException {
 		
-		beginTask(Util.bind("classpath.settingOutputLocationProgress", project.getElementName()), 2); //$NON-NLS-1$
+		beginTask(Messages.bind(Messages.classpath_settingOutputLocationProgress, project.getElementName()), 2); 
 		
 		IPath oldLocation= project.getOutputLocation();
 	
@@ -779,7 +790,7 @@
 	 */
 	protected void updateProjectReferencesIfNecessary() throws JavaModelException {
 		
-		if (this.newRawPath == REUSE_ENTRIES || this.newRawPath == UPDATE_ENTRIES) return;
+		if (this.newRawPath == DO_NOT_SET_ENTRIES || this.newRawPath == DO_NOT_UPDATE_PROJECT_REFS) return;
 		// will run now, or be deferred until next pre-auto-build notification if resource tree is locked
 		JavaModelManager.getJavaModelManager().deltaState.performClasspathResourceChange(
 		        project, 
@@ -799,7 +810,7 @@
 		if (needValidation) {
 			// retrieve classpath 
 			IClasspathEntry[] entries = this.newRawPath;
-			if (entries == REUSE_ENTRIES){
+			if (entries == DO_NOT_SET_ENTRIES){
 				try {
 					entries = project.getRawClasspath();			
 				} catch (JavaModelException e) {
@@ -808,7 +819,7 @@
 			}		
 			// retrieve output location
 			IPath outputLocation = this.newOutputLocation;
-			if (outputLocation == REUSE_PATH){
+			if (outputLocation == DO_NOT_SET_OUTPUT){
 				try {
 					outputLocation = project.getOutputLocation();
 				} catch (JavaModelException e) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java
index 1eed95e..4491164 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SimpleDelta.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java
index 577b051..37d0f11 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SingleTypeRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java
deleted file mode 100644
index 31233cc..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-import java.util.Comparator;
-import java.util.Stack;
-
-import org.eclipse.jdt.core.compiler.InvalidInputException;
-import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.FieldDeclaration;
-import org.eclipse.jdt.core.dom.Initializer;
-import org.eclipse.jdt.core.dom.MethodDeclaration;
-import org.eclipse.jdt.core.dom.Name;
-import org.eclipse.jdt.core.dom.PrimitiveType;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.core.dom.Type;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
-import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-import org.eclipse.jdt.core.util.CompilationUnitSorter;
-import org.eclipse.jdt.internal.compiler.SourceElementRequestorAdapter;
-import org.eclipse.jdt.internal.compiler.env.IConstants;
-import org.eclipse.jdt.internal.compiler.env.IGenericType;
-import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
-import org.eclipse.jdt.internal.compiler.parser.Scanner;
-import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
-
-/**
- * 
- * @since 2.1
- */
-public class SortElementBuilder extends SourceElementRequestorAdapter {
-
-	abstract class SortElement extends SortJavaElement {
-		SortElement(int sourceStart, int modifiers) {
-			super(SortElementBuilder.this);
-			this.sourceStart = normalizeSourceStart(sourceStart);
-			modifiers &= ~IConstants.AccInterface; // remove AccInterface flags
-			modifiers &= CompilerModifiers.AccJustFlag;
-			this.modifiers = modifiers;
-			this.children_count = 0;
-		}
-
-		protected void setParameters(MethodDeclaration methodDeclaration, String[] parameterNames, String[] parameterTypes) {
-			for (int i = 0, max = parameterNames.length; i < max; i++) {
-				String paramType = parameterTypes[i];
-				SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
-				singleVariableDeclaration.setName(ast.newSimpleName(parameterNames[i]));
-				int indexOfArrayBrace;
-				if (paramType.indexOf('.') != -1) {
-					String[] typeParts = splitOn('.', paramType);
-					int length = typeParts.length;
-					indexOfArrayBrace = typeParts[length - 1].indexOf('[');
-					if (indexOfArrayBrace != -1) {
-						int dimensions = occurencesOf('[', typeParts[length - 1]);
-						typeParts[length - 1] = typeParts[length - 1].substring(0, indexOfArrayBrace);
-						String[] typeSubstrings = new String[length];
-						for (int j = 0; j < length; j++) {
-							typeSubstrings[j] = typeParts[j];
-						}
-						singleVariableDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newName(typeSubstrings)), dimensions));
-					} else {
-						String[] typeSubstrings = new String[length];
-						for (int j = 0; j < length; j++) {
-							typeSubstrings[j] = new String(typeParts[j]);
-						}
-						singleVariableDeclaration.setType(ast.newSimpleType(ast.newName(typeSubstrings)));
-					}
-				} else if ((indexOfArrayBrace = paramType.indexOf('[')) != -1) {
-					int dimensions = occurencesOf('[', paramType);
-					paramType = paramType.substring(0, indexOfArrayBrace);
-					singleVariableDeclaration.setType(ast.newArrayType(newType(paramType), dimensions));
-				} else {
-					singleVariableDeclaration.setType(newType(paramType));
-				}
-				methodDeclaration.parameters().add(singleVariableDeclaration);
-			}
-		}
-			
-		protected String[] splitOn(char divider, String stringToSplit) {
-			int length = stringToSplit == null ? 0 : stringToSplit.length();
-			if (length == 0)
-				return new String[] { stringToSplit };
-	
-			int wordCount = 1;
-			for (int i = 0; i < length; i++)
-				if (stringToSplit.charAt(i) == divider)
-					wordCount++;
-			String[] split = new String[wordCount];
-			int last = 0, currentWord = 0;
-			for (int i = 0; i < length; i++) {
-				if (stringToSplit.charAt(i) == divider) {
-					split[currentWord++] = stringToSplit.substring(last, i);
-					last = i + 1;
-				}
-			}
-			split[currentWord] = stringToSplit.substring(last, length);
-			return split;
-		}
-		
-		protected int occurencesOf(char toBeFound, String s) {
-			if (s == null) return 0;
-			int count = 0;
-			for (int i = 0, max = s.length(); i < max; i++)
-				if (toBeFound == s.charAt(i))
-					count++;
-			return count;
-		}
-		
-		protected Type newType(String typeSource) {
-			// check if type is a primitive type
-			scanner.setSource(typeSource.toCharArray());
-			scanner.resetTo(0, typeSource.length());
-			int token = 0;
-			try {
-				token = scanner.getNextToken();
-			} catch(InvalidInputException e) {
-				return null;
-			}
-			if (token == TerminalTokens.TokenNameIdentifier) {
-				return ast.newSimpleType(ast.newSimpleName(typeSource));
-			} else {
-				switch(token) {
-					case TerminalTokens.TokenNameint :
-						return ast.newPrimitiveType(PrimitiveType.INT);
-					case TerminalTokens.TokenNamebyte :
-						return ast.newPrimitiveType(PrimitiveType.BYTE);
-					case TerminalTokens.TokenNameboolean :
-						return ast.newPrimitiveType(PrimitiveType.BOOLEAN);
-					case TerminalTokens.TokenNamechar :
-						return ast.newPrimitiveType(PrimitiveType.CHAR);
-					case TerminalTokens.TokenNamedouble :
-						return ast.newPrimitiveType(PrimitiveType.DOUBLE);
-					case TerminalTokens.TokenNamefloat :
-						return ast.newPrimitiveType(PrimitiveType.FLOAT);
-					case TerminalTokens.TokenNamelong :
-						return ast.newPrimitiveType(PrimitiveType.LONG);
-					case TerminalTokens.TokenNameshort :
-						return ast.newPrimitiveType(PrimitiveType.SHORT);
-					case TerminalTokens.TokenNamevoid :
-						return ast.newPrimitiveType(PrimitiveType.VOID);
-				}
-			}
-			return null;
-		}
-
-		abstract ASTNode convert();
-	}
-	
-	abstract class SortAbstractMethodDeclaration extends SortElement {
-
-		SortAbstractMethodDeclaration(int sourceStart, int modifiers, char[] name, char[][] parametersNames, char[][] parametersTypes, char[][] thrownExceptions) {			
-			super(sourceStart, modifiers);
-			this.name = new String(name);
-			if (parametersNames != null) {
-				int length = parametersNames.length;
-				this.parametersNames = new String[length];
-				this.parametersTypes = new String[length];
-				for (int i = 0; i < length; i++) {
-					this.parametersNames[i] = new String(parametersNames[i]);
-					this.parametersTypes[i] = new String(parametersTypes[i]);
-				}
-			}
-			if (thrownExceptions != null) {
-				int length = thrownExceptions.length;
-				this.thrownExceptions = new String[length];
-				for (int i = 0; i < length; i++) {
-					this.thrownExceptions[i] = new String(thrownExceptions[i]);
-				}
-			}
-
-		}
-		public String decodeSignature() {
-			StringBuffer buffer = new StringBuffer();
-			buffer.append("("); //$NON-NLS-1$
-			if (this.parametersNames != null) {
-				int length = parametersNames.length;
-				for (int i = 0; i < length - 1; i++) {
-					buffer.append(parametersTypes[i] + " " + parametersNames[i] + ", "); //$NON-NLS-1$ //$NON-NLS-2$
-				}
-				buffer.append(parametersTypes[length - 1] + " " + parametersNames[length - 1]); //$NON-NLS-1$
-			}
-			buffer.append(")"); //$NON-NLS-1$
-			return buffer.toString();
-		}
-
-		/**
-		 * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
-		 */
-		protected void generateSource(StringBuffer buffer) {
-			super.generateSource(buffer);
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.sourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-
-				for (int i = 0; i < length; i++) {
-					buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-					this.children[i].generateSource(buffer);
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.sourceEnd;
-					}
-				}
-				buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-			} else {
-				buffer.append(SortElementBuilder.this.source, this.sourceStart, this.sourceEnd - this.sourceStart + 1);
-			}	
-		}
-
-		protected void mapPositions() {
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.sourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-
-				for (int i = 0; i < length; i++) {
-					mapNextPosition(this, start, end);
-					this.children[i].mapPositions();
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.sourceEnd;
-					}
-				}
-				mapNextPosition(this, start, end);
-			} else {
-				mapNextPosition(this, this.sourceStart, this.sourceEnd);
-			}	
-		}
-	}
-	
-	class SortMethodDeclaration extends SortAbstractMethodDeclaration {
-		SortMethodDeclaration(int sourceStart, int modifiers, char[] name, char[][] parametersNames, char[][] parametersTypes, char[][] thrownExceptions, char[] returnType) {			
-			super(sourceStart, modifiers, name, parametersNames, parametersTypes, thrownExceptions);
-			this.id = METHOD;
-			if (returnType != null) {
-				this.returnType = new String(returnType);
-			}
-		}
-		
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("method ") //$NON-NLS-1$
-				.append(name)
-				.append(decodeSignature());
-			if (returnType != null) {
-				buffer.append(" " + returnType + LINE_SEPARATOR); //$NON-NLS-1$
-			} else {
-				buffer.append(LINE_SEPARATOR); //$NON-NLS-1$
-			}
-		}
-		
-		ASTNode convert() {
-			MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
-			methodDeclaration.setConstructor(false);
-			methodDeclaration.setModifiers(this.modifiers);
-			methodDeclaration.setName(ast.newSimpleName(this.name));
-			methodDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));
-			// set parameter names and types
-			if (this.parametersNames != null) {
-				setParameters(methodDeclaration, this.parametersNames, this.parametersTypes);
-			}
-			// set thrown exceptions
-			if (this.thrownExceptions != null) {
-				for (int j = 0, max2 = this.thrownExceptions.length; j < max2; j++) {
-					String currentException = this.thrownExceptions[j];
-					Name exceptionName;
-					if (currentException.indexOf('.') == -1) {
-						exceptionName = ast.newSimpleName(currentException);
-					} else {
-						exceptionName = ast.newName(splitOn('.', currentException));
-					}
-					methodDeclaration.thrownExceptions().add(exceptionName);
-				}
-			}
-			// set return type
-			int indexOfArrayBrace;
-			String currentReturnType = this.returnType;
-			if (currentReturnType != null) {
-				if (currentReturnType.indexOf('.') != -1) {
-					String[] returnTypeSubstrings = splitOn('.', currentReturnType);
-					int length = returnTypeSubstrings.length;
-					indexOfArrayBrace = returnTypeSubstrings[length - 1].indexOf('[');
-					if (indexOfArrayBrace != -1) {
-						int dimensions = occurencesOf('[', returnTypeSubstrings[length - 1]);
-						returnTypeSubstrings[length - 1] = returnTypeSubstrings[length - 1].substring(0, indexOfArrayBrace);
-						methodDeclaration.setReturnType(ast.newArrayType(ast.newSimpleType(ast.newName(returnTypeSubstrings)), dimensions));
-					} else {
-						methodDeclaration.setReturnType(ast.newSimpleType(ast.newName(returnTypeSubstrings)));
-					}
-				} else if ((indexOfArrayBrace = currentReturnType.indexOf('[')) != -1) {
-					int dimensions = occurencesOf('[', currentReturnType);
-					currentReturnType = currentReturnType.substring(0, indexOfArrayBrace);
-					methodDeclaration.setReturnType(ast.newArrayType(newType(currentReturnType), dimensions));
-				} else {
-					methodDeclaration.setReturnType(newType(currentReturnType));
-				}
-			}
-			return methodDeclaration;				
-		}
-	}
-
-	class SortConstructorDeclaration extends SortAbstractMethodDeclaration {
-		SortConstructorDeclaration(int sourceStart, int modifiers, char[] name, char[][] parametersNames, char[][] parametersTypes, char[][] thrownExceptions) {			
-			super(sourceStart, modifiers, name, parametersNames, parametersTypes, thrownExceptions);
-			this.id = CONSTRUCTOR;
-		}
-
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("constructor ") //$NON-NLS-1$
-				.append(decodeSignature() + LINE_SEPARATOR);
-		}
-		
-		ASTNode convert() {
-			MethodDeclaration methodDeclaration = ast.newMethodDeclaration();
-			methodDeclaration.setConstructor(true);
-			methodDeclaration.setModifiers(this.modifiers);
-			methodDeclaration.setName(ast.newSimpleName(this.name));
-			methodDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));
-			// set parameter names and types
-			if (this.parametersNames != null) {
-				setParameters(methodDeclaration, this.parametersNames, this.parametersTypes);
-			}
-			// set thrown exceptions
-			if (this.thrownExceptions != null) {
-				for (int j = 0, max2 = this.thrownExceptions.length; j < max2; j++) {
-					String currentException = this.thrownExceptions[j];
-					Name exceptionName;
-					if (currentException.indexOf('.') == -1) {
-						exceptionName = ast.newSimpleName(currentException);
-					} else {
-						exceptionName = ast.newName(splitOn('.', currentException));
-					}
-					methodDeclaration.thrownExceptions().add(exceptionName);
-				}
-			}
-			return methodDeclaration;
-		}			
-	}
-	
-	public class SortFieldDeclaration extends SortElement {
-		int previousSourceEnd;
-
-		SortFieldDeclaration(int sourceStart, int modifiers, char[] type, char[] name, int nameSourceStart) {
-			super(sourceStart, modifiers);
-			this.declarationStart = sourceStart;
-			this.id = FIELD;
-			this.type = new String(type);
-			this.name = new String(name);
-			this.nameSourceStart = nameSourceStart;
-		}
-
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("field ") //$NON-NLS-1$
-				.append(type + " " + name + LINE_SEPARATOR); //$NON-NLS-1$
-		}
-		
-		ASTNode convert() {
-			VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
-			variableDeclarationFragment.setName(ast.newSimpleName(this.name));
-			FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(variableDeclarationFragment);
-
-			String currentFieldType = this.type;
-			
-			int indexOfArrayBrace;
-			if (currentFieldType.indexOf('.') != -1) {
-				String[] typeParts = splitOn('.', currentFieldType);
-				int length = typeParts.length;
-				indexOfArrayBrace = typeParts[length - 1].indexOf('[');
-				if (indexOfArrayBrace != -1) {
-					int dimensions = occurencesOf('[', typeParts[length - 1]);
-					typeParts[length - 1] = typeParts[length - 1].substring(0, indexOfArrayBrace);
-					fieldDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newName(typeParts)), dimensions));
-				} else {
-					fieldDeclaration.setType(ast.newSimpleType(ast.newName(typeParts)));
-				}
-			} else if ((indexOfArrayBrace = currentFieldType.indexOf('[')) != -1) {
-				int dimensions = occurencesOf('[', currentFieldType);
-				currentFieldType = currentFieldType.substring(0, indexOfArrayBrace);
-				fieldDeclaration.setType(ast.newArrayType(newType(currentFieldType), dimensions));
-			} else {
-				fieldDeclaration.setType(newType(currentFieldType));
-			}
-			fieldDeclaration.setModifiers(this.modifiers);
-			fieldDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));
-			return fieldDeclaration;
-		}
-		/**
-		 * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
-		 */
-		protected void generateSource(StringBuffer buffer) {
-			super.generateSource(buffer);
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.sourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-
-				for (int i = 0; i < length; i++) {
-					buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-					this.children[i].generateSource(buffer);
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.declarationSourceEnd;
-					}
-				}
-				buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-			} else {
-				buffer.append(SortElementBuilder.this.source, this.sourceStart, this.declarationSourceEnd - this.sourceStart + 1);
-			}	
-		}
-		protected void generateReduceSource(StringBuffer buffer) {
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.nameSourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-	
-				for (int i = 0; i < length; i++) {
-					buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-					this.children[i].generateSource(buffer);
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.sourceEnd;
-					}
-				}
-				buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-			} else {
-				buffer.append(SortElementBuilder.this.source, this.nameSourceStart, this.sourceEnd - this.nameSourceStart + 1);
-			}	
-		}
-		protected void mapReducedPositions() {
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.nameSourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-				mapNextPosition(this, start, end);
-				for (int i = 0; i < length; i++) {
-					this.children[i].mapPositions();
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.sourceEnd;
-					}
-				}
-				mapNextPosition(this, start, end);
-			} else {
-				mapNextPosition(this, this.nameSourceStart, this.sourceEnd);
-			}	
-		}
-		
-		protected void mapPositions() {
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.sourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-
-				for (int i = 0; i < length; i++) {
-					mapNextPosition(this, start, end);
-					this.children[i].mapPositions();
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.declarationSourceEnd;
-					}
-				}
-				mapNextPosition(this, start, end);
-			} else {
-				mapNextPosition(this, this.sourceStart, this.declarationSourceEnd);
-			}	
-		}
-	}
-	
-	class SortMultipleFieldDeclaration extends SortElement {
-		SortMultipleFieldDeclaration(SortFieldDeclaration fieldDeclaration) {
-			super(fieldDeclaration.declarationStart, fieldDeclaration.modifiers);
-			this.declarationStart = fieldDeclaration.declarationStart;
-			this.id = MULTIPLE_FIELD;
-			this.innerFields = new SortFieldDeclaration[1];
-			this.fieldCounter = 0;
-			this.innerFields[this.fieldCounter++] = fieldDeclaration;
-			this.type = fieldDeclaration.type;
-			this.sourceStart = fieldDeclaration.sourceStart;
-			fieldDeclaration.sourceEnd = fieldDeclaration.previousSourceEnd;
-		}
-		
-		void addField(SortFieldDeclaration fieldDeclaration) {
-			System.arraycopy(this.innerFields, 0, this.innerFields = new SortFieldDeclaration[this.fieldCounter + 1], 0, this.fieldCounter);
-			this.innerFields[this.fieldCounter++] = fieldDeclaration;
-			fieldDeclaration.sourceEnd = fieldDeclaration.previousSourceEnd;
-		}
-		
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("multiple fields ") //$NON-NLS-1$
-				.append(LINE_SEPARATOR);
-			if (this.innerFields != null) {
-				buffer
-					.append(tab(tab + 1))
-					.append("INNER FIELDS ------------------------------" + LINE_SEPARATOR); //$NON-NLS-1$
-				for (int i = 0; i < this.fieldCounter; i++) {
-					buffer.append(this.innerFields[i].toString(tab + 2));
-					buffer.append(LINE_SEPARATOR);
-				}
-			}
-		}
-
-		ASTNode convert() {
-			VariableDeclarationFragment variableDeclarationFragment = ast.newVariableDeclarationFragment();
-			variableDeclarationFragment.setName(ast.newSimpleName(this.innerFields[0].name));
-			FieldDeclaration fieldDeclaration = ast.newFieldDeclaration(variableDeclarationFragment);
-
-			for (int j = 1, max2 = this.innerFields.length; j < max2; j++) {
-				VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment();
-				fragment.setName(ast.newSimpleName(new String(this.innerFields[j].name)));
-			}
-			String currentFieldType = this.type;
-			
-			int indexOfArrayBrace;
-			if (currentFieldType.indexOf('.') != -1) {
-				String[] typeParts = splitOn('.', currentFieldType);
-				int length = typeParts.length;
-				indexOfArrayBrace = typeParts[length - 1].indexOf('[');
-				if (indexOfArrayBrace != -1) {
-					int dimensions = occurencesOf('[', typeParts[length - 1]);
-					typeParts[length - 1] = typeParts[length - 1].substring(0, indexOfArrayBrace);
-					fieldDeclaration.setType(ast.newArrayType(ast.newSimpleType(ast.newName(typeParts)), dimensions));
-				} else {
-					fieldDeclaration.setType(ast.newSimpleType(ast.newName(typeParts)));
-				}
-			} else if ((indexOfArrayBrace = currentFieldType.indexOf('[')) != -1) {
-				int dimensions = occurencesOf('[', currentFieldType);
-				currentFieldType = currentFieldType.substring(0, indexOfArrayBrace);
-				fieldDeclaration.setType(ast.newArrayType(newType(currentFieldType), dimensions));
-			} else {
-				fieldDeclaration.setType(newType(currentFieldType));
-			}
-			fieldDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));
-			fieldDeclaration.setModifiers(this.modifiers);
-			return fieldDeclaration;
-		}
-		/**
-		 * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
-		 */
-		protected void generateSource(StringBuffer buffer) {
-			super.generateSource(buffer);
-			int length = this.fieldCounter;
-			int start = this.innerFields[0].sourceStart;
-			int end = this.innerFields[0].nameSourceStart - 1;
-			buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-			for (int i = 0; i < length; i++) {
-				this.innerFields[i].newSourceStart = this.newSourceStart;
-				this.innerFields[i].generateReduceSource(buffer);
-				if (i < length - 1) {
-					start = this.innerFields[i].sourceEnd + 1;
-					end = this.innerFields[i + 1].nameSourceStart - 1;
-					buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-				}
-			}
-			start = this.innerFields[length - 1].sourceEnd + 1;
-			end = this.innerFields[length - 1].declarationSourceEnd;
-			buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-		}
-
-		protected void mapPositions() {
-			int length = this.fieldCounter;
-			int start = this.innerFields[0].sourceStart;
-			int end = this.innerFields[0].nameSourceStart - 1;
-			mapNextPosition(this, start, end);
-			for (int i = 0; i < length; i++) {
-				this.innerFields[i].newSourceStart = this.newSourceStart;
-				this.innerFields[i].mapReducedPositions();
-				if (i < length - 1) {
-					start = this.innerFields[i].sourceEnd + 1;
-					end = this.innerFields[i + 1].nameSourceStart - 1;
-					mapNextPosition(this, start, end);
-				}
-			}
-			start = this.innerFields[length - 1].sourceEnd + 1;
-			end = this.innerFields[length - 1].declarationSourceEnd;
-			mapNextPosition(this, start, end);
-		}
-
-		protected void sort() {
-			for (int i = 0, max = this.fieldCounter; i < max; i++) {
-				this.innerFields[i].sort();
-			}
-		}
-	}
-
-	class SortInitializer extends SortElement {
-		SortInitializer(int sourceStart, int modifiers) {
-			super(sourceStart, modifiers);
-			this.id = INITIALIZER;
-		}
-
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("initializer " + LINE_SEPARATOR); //$NON-NLS-1$
-		}
-		
-		ASTNode convert() {
-			Initializer initializer = ast.newInitializer();
-			initializer.setModifiers(this.modifiers);
-			initializer.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));
-			return initializer;
-		}
-		/**
-		 * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
-		 */
-		protected void generateSource(StringBuffer buffer) {
-			super.generateSource(buffer);
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.sourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-		
-				for (int i = 0; i < length; i++) {
-					buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-					this.children[i].generateSource(buffer);
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.sourceEnd;
-					}
-				}
-				buffer.append(SortElementBuilder.this.source, start, end - start + 1);
-			} else {
-				buffer.append(SortElementBuilder.this.source, this.sourceStart, this.sourceEnd - this.sourceStart + 1);
-			}	
-		}
-
-		protected void mapPositions() {
-			int length = this.children_count;
-			if (length != 0) {
-				int start = this.sourceStart;
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-		
-				for (int i = 0; i < length; i++) {
-					mapNextPosition(this, start, end);
-					this.children[i].mapPositions();
-					if (i < length - 1) {
-						start = this.children[i].sourceEnd + 1;
-					} else {
-						start = this.lastChildBeforeSorting.sourceEnd + 1;
-					}
-					if (i < length - 1) {
-						end = this.children[i + 1].sourceStart - 1;
-					} else {
-						end = this.sourceEnd;
-					}
-				}
-				mapNextPosition(this, start, end);
-			} else {
-				mapNextPosition(this, this.sourceStart, this.sourceEnd);
-			}	
-		}
-	}
-
-	class SortClassDeclaration extends SortType  {
-		SortClassDeclaration(int sourceStart, int modifiers, char[] name, char[] superclass, char[][] superinterfaces) {
-			super(sourceStart, modifiers, name, superinterfaces);
-			this.id = CLASS | TYPE;
-			if (superclass != null) {
-				this.superclass = new String(superclass);
-			}
-		}
-
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("class ") //$NON-NLS-1$
-				.append(this.name);
-			if (this.superclass != null) {
-				buffer.append(" extends " + this.superclass); //$NON-NLS-1$
-			}
-			if (this.superInterfaces != null) {
-				int length = this.superInterfaces.length;
-				buffer.append(" implements "); //$NON-NLS-1$
-				for (int i = 0; i < length - 1; i++) {
-					buffer.append(this.superInterfaces[i] + ", "); //$NON-NLS-1$
-				}
-				buffer.append(this.superInterfaces[length - 1]);
-			}
-			buffer.append(LINE_SEPARATOR);
-		}
-		
-		ASTNode convert() {
-			TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
-			typeDeclaration.setInterface(false);
-			typeDeclaration.setModifiers(this.modifiers);
-			typeDeclaration.setName(ast.newSimpleName(this.name));
-			// set superclass
-			if (this.superclass != null) {
-				if (this.superclass.indexOf('.') == -1) {
-					// the superclass is a simple name
-					typeDeclaration.setSuperclass(ast.newSimpleName(this.superclass));
-				} else {
-					// the superclass is a qualified name
-					String[] superclassNames = splitOn('.', this.superclass);
-					typeDeclaration.setSuperclass(ast.newName(superclassNames));
-				}
-			}
-			// set superinterfaces
-			if (this.superInterfaces != null) {
-				for (int j = 0, max2 = this.superInterfaces.length; j < max2; j++) {
-					String currentInterfaceName = this.superInterfaces[j];
-					Name interfaceName;
-					if (currentInterfaceName.indexOf('.') == -1) {
-						// the superclass is a simple name
-						interfaceName = ast.newSimpleName(currentInterfaceName);
-					} else {
-						// the superclass is a qualified name
-						String[] interfaceNames = splitOn('.', currentInterfaceName);
-						interfaceName = ast.newName(interfaceNames);
-					}
-					typeDeclaration.superInterfaces().add(interfaceName);
-				}
-			}
-			typeDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));				
-			return typeDeclaration;
-		}			
-	}
-
-	abstract class SortType extends SortElement {
-		SortType(int sourceStart, int modifier, char[] name, char[][] superinterfaces) {
-			super(sourceStart, modifier);
-			this.name = new String(name);
-			if (superinterfaces != null) {
-				int length = superinterfaces.length;
-				this.superInterfaces = new String[length];
-				for (int i = 0; i < length; i++) {
-					this.superInterfaces[i] = new String(superinterfaces[i]);
-				}
-			}
-		}
-		/**
-		 * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
-		 */
-		protected void generateSource(StringBuffer buffer) {
-			super.generateSource(buffer);
-			int length = this.children_count;
-			int start = this.sourceStart;
-			if (length != 0) {
-				int end = this.firstChildBeforeSorting.sourceStart;
-				
-				buffer.append(SortElementBuilder.this.source, start, end - start);
-				for (int i = 0; i < length; i++) {
-					((SortElementBuilder.SortElement)this.astNodes[i].getProperty(CORRESPONDING_ELEMENT)).generateSource(buffer);
-				}
-				start = this.lastChildBeforeSorting.sourceEnd + 1;
-				buffer.append(SortElementBuilder.this.source, start, this.sourceEnd - start + 1);
-			} else {
-				buffer.append(SortElementBuilder.this.source, start, this.sourceEnd - start + 1);
-			}
-		}
-
-		protected void mapPositions() {
-			int length = this.children_count;
-			int start = this.sourceStart;
-			if (length != 0) {
-				int end = this.firstChildBeforeSorting.sourceStart - 1;
-				mapNextPosition(this, start, end);
-				for (int i = 0; i < length; i++) {
-					children[i].mapPositions();
-				}
-				start = this.lastChildBeforeSorting.sourceEnd + 1;
-				mapNextPosition(this, start, this.sourceEnd);
-			} else {
-				mapNextPosition(this, start, this.sourceEnd);
-			}
-		}
-	}
-	
-	class SortInterfaceDeclaration extends SortType {
-		SortInterfaceDeclaration(int sourceStart, int modifiers, char[] name, char[][] superinterfaces) {
-			super(sourceStart, modifiers, name, superinterfaces);
-			this.id = TYPE | INTERFACE;
-		}
-		void display(StringBuffer buffer, int tab) {
-			buffer
-				.append(tab(tab))
-				.append("interface ") //$NON-NLS-1$
-				.append(this.name);
-			if (this.superInterfaces != null) {
-				int length = this.superInterfaces.length;
-				buffer.append(" implements "); //$NON-NLS-1$
-				for (int i = 0; i < length - 1; i++) {
-					buffer.append(this.superInterfaces[i] + ", "); //$NON-NLS-1$
-				}
-				buffer.append(this.superInterfaces[length - 1]);
-			}
-			buffer.append(LINE_SEPARATOR);
-		}
-		ASTNode convert() {
-			TypeDeclaration typeDeclaration = ast.newTypeDeclaration();
-			typeDeclaration.setInterface(true);
-			typeDeclaration.setModifiers(this.modifiers);
-			typeDeclaration.setName(ast.newSimpleName(this.name));
-			// set superinterfaces
-			if (this.superInterfaces != null) {
-				for (int j = 0, max2 = this.superInterfaces.length; j < max2; j++) {
-					String currentInterfaceName = this.superInterfaces[j];
-					Name interfaceName;
-					if (currentInterfaceName.indexOf('.') == -1) {
-						// the superclass is a simple name
-						interfaceName = ast.newSimpleName(currentInterfaceName);
-					} else {
-						// the superclass is a qualified name
-						String[] interfaceNames = splitOn('.', currentInterfaceName);
-						interfaceName = ast.newName(interfaceNames);
-					}
-					typeDeclaration.superInterfaces().add(interfaceName);
-				}
-			}
-			typeDeclaration.setProperty(CompilationUnitSorter.RELATIVE_ORDER, new Integer(this.sourceStart));				
-			return typeDeclaration;
-		}			
-	}
-	
-	class SortCompilationUnit extends SortElement {
-		SortCompilationUnit(int sourceStart) {
-			super(sourceStart, 0);
-			this.id = COMPILATION_UNIT;
-		}
-		void display(StringBuffer buffer, int tab) {
-			// nothing to do
-		}
-		
-		ASTNode convert() {
-			return ast.newCompilationUnit();
-		}
-		/**
-		 * @see org.eclipse.jdt.internal.core.SortElementBuilder.SortElement#generateSource(java.lang.StringBuffer)
-		 */
-		protected void generateSource(StringBuffer buffer) {
-			super.generateSource(buffer);
-			int length = this.children_count;
-			if (length != 0) {
-				int end = this.firstChildBeforeSorting.sourceStart;
-				int start = this.lastChildBeforeSorting.sourceEnd + 1;
-				buffer.append(SortElementBuilder.this.source, 0, end);
-				for (int i = 0; i < length; i++) {
-					((SortElementBuilder.SortElement)this.astNodes[i].getProperty(CORRESPONDING_ELEMENT)).generateSource(buffer);
-				}
-				buffer.append(SortElementBuilder.this.source, start, this.sourceEnd - start + 1);
-			}
-		}
-
-		protected void mapPositions() {
-			int length = this.children_count;
-			if (length != 0) {
-				int end = this.firstChildBeforeSorting.sourceStart;
-				int start = this.lastChildBeforeSorting.sourceEnd + 1;
-				mapNextPosition(this, 0, end);
-				for (int i = 0; i < length; i++) {
-					children[i].mapPositions();
-				}
-				mapNextPosition(this, start, this.sourceEnd);
-			} else {
-				mapNextPosition(this, this.sourceStart, this.sourceEnd);
-			}
-		}
-	}
-
-	SortElement currentElement;
-	Stack stack;
-	SortCompilationUnit compilationUnit;
-	Scanner scanner;
-	AST ast;
-
-	char[] source;
-	int[] lineEnds;
-	Comparator comparator;
-	int[] positionsToMap;
-	int positionsToMapIndex;
-	
-	public SortElementBuilder(char[] source, int[] positionsToMap, Comparator comparator, CompilerOptions options) {
-		this.source = source;
-		this.comparator = comparator;
-		this.positionsToMap = positionsToMap;
-		this.ast = AST.newAST(AST.JLS2);
-		this.scanner = new Scanner(false, false, false, options.sourceLevel/*sourceLevel*/, null, null, true/*taskCaseSensitive*/);
-	}
-	
-	/*
-	 * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
-	 */
-	public void acceptLineSeparatorPositions(int[] positions) {
-		this.lineEnds = positions;
-	}
-		
-	public String getSource() {
-		StringBuffer buffer = new StringBuffer();
-		this.positionsToMapIndex = 0;
-		this.compilationUnit.generateSource(buffer);
-		if (this.positionsToMap != null) {
-			this.compilationUnit.mapPositions();
-		}
-		return buffer.toString();
-	}
-
-	private static int searchLineNumber(
-		int[] startLineIndexes,
-		int position) {
-		// this code is completely useless, but it is the same implementation than
-		// org.eclipse.jdt.internal.compiler.problem.ProblemHandler.searchLineNumber(int[], int)
-		// if (startLineIndexes == null)
-		//	return 1;
-		int length = startLineIndexes.length;
-		if (length == 0)
-			return 1;
-		int g = 0, d = length - 1;
-		int m = 0;
-		while (g <= d) {
-			m = (g + d) / 2;
-			if (position < startLineIndexes[m]) {
-				d = m - 1;
-			} else
-				if (position > startLineIndexes[m]) {
-					g = m + 1;
-				} else {
-					return m + 1;
-				}
-		}
-		if (position < startLineIndexes[m]) {
-			return m + 1;
-		}
-		return m + 2;
-	}
-	
-	void sort() {
-		this.compilationUnit.sort();
-	}
-
-	void mapNextPosition(SortJavaElement node, int start, int end) {
-		int i = this.positionsToMapIndex;
-		for (; i < this.positionsToMap.length; i++) {
-			int nextPosition = this.positionsToMap[i];
-			if (nextPosition >= start
-				&& nextPosition <= end) {
-					this.positionsToMap[i] += (node.newSourceStart - node.sourceStart);
-				} else {
-					break;
-				}
-		}
-		this.positionsToMapIndex = i;
-	}
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterCompilationUnit()
-	 */
-	public void enterCompilationUnit() {
-		this.stack = new Stack();
-		push(this.compilationUnit = new SortCompilationUnit(0));
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterConstructor(MethodInfo)
-	 */
-	public void enterConstructor(MethodInfo methodInfo) {
-		if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
-			SortConstructorDeclaration constructorDeclaration = new SortConstructorDeclaration(methodInfo.declarationStart, methodInfo.modifiers, methodInfo.name, methodInfo.parameterNames, methodInfo.parameterTypes, methodInfo.exceptionTypes);
-			this.currentElement.addChild(constructorDeclaration);
-			push(constructorDeclaration);
-		}
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterField(FieldInfo)
-	 */
-	public void enterField(FieldInfo fieldInfo) {
-			if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
-				SortFieldDeclaration fieldDeclaration = new SortFieldDeclaration(fieldInfo.declarationStart, fieldInfo.modifiers, fieldInfo.type, fieldInfo.name, fieldInfo.nameSourceStart);
-				SortElement[] currentElementChildren = this.currentElement.children;
-				if (currentElementChildren != null) {
-					SortElement previousElement = this.currentElement.children[this.currentElement.children_count - 1];
-					if (previousElement.id == SortJavaElement.FIELD && ((SortFieldDeclaration) previousElement).declarationStart == fieldInfo.declarationStart) {
-						SortMultipleFieldDeclaration multipleFielDeclaration = new SortMultipleFieldDeclaration((SortFieldDeclaration) previousElement);
-						multipleFielDeclaration.addField(fieldDeclaration);
-						this.currentElement.children[this.currentElement.children_count - 1] = multipleFielDeclaration;
-					} else if (previousElement.id == SortJavaElement.MULTIPLE_FIELD && ((SortMultipleFieldDeclaration) previousElement).declarationStart == fieldInfo.declarationStart) {
-						((SortMultipleFieldDeclaration) previousElement).addField(fieldDeclaration);
-					} else {
-						this.currentElement.addChild(fieldDeclaration);
-					}
-				} else {
-					this.currentElement.addChild(fieldDeclaration);
-				}
-				push(fieldDeclaration);
-			}
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterInitializer(int, int)
-	 */
-	public void enterInitializer(int declarationStart, int modifiers) {
-		if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
-			SortInitializer initializer = new SortInitializer(declarationStart, modifiers);
-			this.currentElement.addChild(initializer);
-			push(initializer);
-		}
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterMethod(MethodInfo)
-	 */
-	public void enterMethod(MethodInfo methodInfo) {
-		if ((this.currentElement.id & SortJavaElement.TYPE) != 0) {
-			SortMethodDeclaration methodDeclaration = new SortMethodDeclaration(methodInfo.declarationStart, methodInfo.modifiers, methodInfo.name, methodInfo.parameterNames, methodInfo.parameterTypes, methodInfo.exceptionTypes, methodInfo.returnType);
-			this.currentElement.addChild(methodDeclaration);
-			push(methodDeclaration);
-		}
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#enterType(TypeInfo)
-	 */
-	public void enterType(TypeInfo typeInfo) {
-		SortType type = null;
-		switch (typeInfo.kind) {
-			case IGenericType.CLASS_DECL:
-			case IGenericType.ANNOTATION_TYPE_DECL: // TODO (olivier) might need a SortAnnotationTypeDeclaration
-				type = new SortClassDeclaration(typeInfo.declarationStart, typeInfo.modifiers, typeInfo.name, typeInfo.superclass, typeInfo.superinterfaces);
-				break;
-			case IGenericType.INTERFACE_DECL:
-			case IGenericType.ENUM_DECL: // TODO (olivier) might need a SortEnumDeclaration
-				type = new SortInterfaceDeclaration(typeInfo.declarationStart, typeInfo.modifiers, typeInfo.name, typeInfo.superinterfaces);
-				break;
-		}
-		this.currentElement.addChild(type);
-		push(type);
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitCompilationUnit(int)
-	 */
-	public void exitCompilationUnit(int declarationEnd) {
-		pop(declarationEnd);
-		sort();
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitConstructor(int)
-	 */
-	public void exitConstructor(int declarationEnd) {
-		pop(declarationEnd);
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitField(int, int, int)
-	 */
-	public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
-		int normalizedDeclarationSourceEnd = this.normalizeSourceEnd(declarationSourceEnd);
-		if (this.currentElement.id == SortJavaElement.FIELD) {
-			SortFieldDeclaration fieldDeclaration = (SortFieldDeclaration) this.currentElement;
-			fieldDeclaration.declarationSourceEnd = normalizedDeclarationSourceEnd;
-		}
-		pop(declarationEnd);
-		if (this.currentElement.children != null) {
-			SortElement element = this.currentElement.children[this.currentElement.children_count - 1];
-			switch(element.id) {
-				case SortJavaElement.MULTIPLE_FIELD :
-					SortMultipleFieldDeclaration multipleFielDeclaration = (SortMultipleFieldDeclaration) element;
-					multipleFielDeclaration.innerFields[multipleFielDeclaration.fieldCounter - 1].declarationSourceEnd = normalizedDeclarationSourceEnd;
-					multipleFielDeclaration.sourceEnd = normalizedDeclarationSourceEnd;
-					break;
-				case SortJavaElement.FIELD :
-					SortFieldDeclaration fieldDeclaration = (SortFieldDeclaration) element;
-					/*
-					 * we will revert to the previous source end in case this field is
-					 * part of a multiple field declaration
-					 */
-					fieldDeclaration.previousSourceEnd = fieldDeclaration.sourceEnd;
-					fieldDeclaration.sourceEnd = normalizedDeclarationSourceEnd;
-			}
-		}
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitInitializer(int)
-	 */
-	public void exitInitializer(int declarationEnd) {
-		pop(declarationEnd);
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitMethod(int, int, int)
-	 */
-	public void exitMethod(int declarationEnd, int defaultValueStart, int defaultValueEnd) {
-		pop(declarationEnd);
-	}
-
-	/**
-	 * @see org.eclipse.jdt.internal.compiler.ISourceElementRequestor#exitType(int)
-	 */
-	public void exitType(int declarationEnd) {
-		pop(declarationEnd);
-	}
-
-	final int normalizeSourceStart(int position) {
-		if (position == 0) {
-			return 0;
-		}
-		int index = position - 1;
-		while(index >= 0 && Character.isWhitespace(this.source[index])) {
-			index--;
-		}
-		
-		int originalLineNumber = searchLineNumber(this.lineEnds, position);
-		int newLineNumber = searchLineNumber(this.lineEnds, index);
-		
-		if (originalLineNumber == newLineNumber) {
-			return index + 1;
-		} else {
-			return this.lineEnds[newLineNumber - 1] + 1;
-		}
-	}
-
-	final int normalizeSourceEnd(int position) {
-		int lineNumber = searchLineNumber(this.lineEnds, position);
-		if (lineNumber == 1) {
-			return position;
-		}
-		int normalizeSourceEnd = 0;
-		if (lineNumber - 1 >= this.lineEnds.length) {
-			normalizeSourceEnd = this.source.length - 1;
-		} else {
-			normalizeSourceEnd = this.lineEnds[lineNumber - 1];
-		}
-		int index = position + 1;
-		while (index < normalizeSourceEnd && Character.isWhitespace(this.source[index])) {
-			index++;
-		}
-		if (index == normalizeSourceEnd) {
-			return normalizeSourceEnd;
-		} else {
-			return position;
-		}
-	}
-	
-	private void pop(int declarationEnd) {
-		this.currentElement.sourceEnd = normalizeSourceEnd(declarationEnd);
-		this.currentElement.closeCollections();
-		this.stack.pop();
-		if (!this.stack.isEmpty()) {
-			this.currentElement = (SortElement) this.stack.peek();
-		}
-	}
-	
-	private void push(SortElement sortElement) {
-		this.currentElement = sortElement;
-		this.stack.push(sortElement);
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
index 29fbf3d..153d2e2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementsOperation.java
@@ -1,17 +1,19 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Comparator;
-import java.util.Locale;
+import java.util.List;
 
 import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.ICompilationUnit;
@@ -20,10 +22,22 @@
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.SourceElementParser;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.core.builder.ProblemFactory;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.text.edits.RangeMarker;
+import org.eclipse.text.edits.TextEdit;
 
 /**
  * This operation is used to sort elements in a compilation unit according to
@@ -61,7 +75,7 @@
 	 */
 	protected void executeOperation() throws JavaModelException {
 		try {
-			beginTask(Util.bind("operation.sortelements"), getMainAmountOfWork()); //$NON-NLS-1$
+			beginTask(Messages.operation_sortelements, getMainAmountOfWork()); 
 			CompilationUnit copy = (CompilationUnit) this.elementsToProcess[0];
 			ICompilationUnit unit = copy.getPrimary();
 			IBuffer buffer = copy.getBuffer();
@@ -69,7 +83,7 @@
 				return;
 			}
 			char[] bufferContents = buffer.getCharacters();
-			String result = processElement(unit, this.positions, bufferContents);
+			String result = processElement(unit, bufferContents);
 			if (!CharOperation.equals(result.toCharArray(), bufferContents)) {
 				copy.getBuffer().setContents(result);
 			}
@@ -82,38 +96,133 @@
 	/**
 	 * Method processElement.
 	 * @param unit
-	 * @param positionsToMap
 	 * @param source
 	 */
-	private String processElement(ICompilationUnit unit, int[] positionsToMap, char[] source) {
+	private String processElement(ICompilationUnit unit, char[] source) {
 		CompilerOptions options = new CompilerOptions(unit.getJavaProject().getOptions(true));
-		SortElementBuilder builder = new SortElementBuilder(source, positionsToMap, this.comparator, options);
-		SourceElementParser parser = new SourceElementParser(builder,
-			ProblemFactory.getProblemFactory(Locale.getDefault()), options, true);
+		ASTParser parser = ASTParser.newParser(AST.JLS3);
+		parser.setCompilerOptions(options.getMap());
+		parser.setSource(source);
+		parser.setKind(ASTParser.K_COMPILATION_UNIT);
+		parser.setResolveBindings(false);
+		org.eclipse.jdt.core.dom.CompilationUnit domUnit = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+		final AST localAst = domUnit.getAST();
+		final ASTRewrite rewriter = ASTRewrite.create(localAst);
+		RangeMarker[] markers = null;
 		
-		if (unit.exists()) {
-			PackageFragment packageFragment = (PackageFragment)unit.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
-			char[][] expectedPackageName = null;
-			if (packageFragment != null){
-				expectedPackageName = Util.toCharArrays(packageFragment.names);
+		final boolean needPositionsMapping = this.positions != null;
+		if (needPositionsMapping) {
+			markers = new RangeMarker[this.positions.length];
+			for (int i= 0; i < this.positions.length; i++) {
+				markers[i]= new RangeMarker(this.positions[i], 0);
 			}
-			parser.parseCompilationUnit(
-				new BasicCompilationUnit(
-					source,
-					expectedPackageName,
-					unit.getElementName(),
-					unit),
-				false/*diet parse*/);
-		} else {
-			parser.parseCompilationUnit(
-				new BasicCompilationUnit(
-					source,
-					null,
-					"",//$NON-NLS-1$
-					unit.getJavaProject()),//$NON-NLS-1$
-				false/*diet parse*/);
 		}
-		return builder.getSource();
+		String generatedSource = new String(source);
+		Document document = new Document(generatedSource);
+		domUnit.accept(new ASTVisitor() {
+			public boolean visit(org.eclipse.jdt.core.dom.CompilationUnit compilationUnit) {
+				ListRewrite listRewrite = rewriter.getListRewrite(compilationUnit, org.eclipse.jdt.core.dom.CompilationUnit.TYPES_PROPERTY);
+				List types = compilationUnit.types();
+				final int length = types.size();
+				if (length > 1) {
+					final List myCopy = new ArrayList();
+					myCopy.addAll(types);
+					Collections.sort(myCopy, SortElementsOperation.this.comparator);
+					for (int i = 0; i < length; i++) {
+						listRewrite.replace((ASTNode) types.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
+					}
+				}
+				return true;
+			}
+			public boolean visit(AnnotationTypeDeclaration annotationTypeDeclaration) {
+				ListRewrite listRewrite = rewriter.getListRewrite(annotationTypeDeclaration, AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY);
+				List bodyDeclarations = annotationTypeDeclaration.bodyDeclarations();
+				final int length = bodyDeclarations.size();
+				if (length > 1) {
+					final List myCopy = new ArrayList();
+					myCopy.addAll(bodyDeclarations);
+					Collections.sort(myCopy, SortElementsOperation.this.comparator);
+					for (int i = 0; i < length; i++) {
+						listRewrite.replace((ASTNode) bodyDeclarations.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
+					}
+				}
+				return true;
+			}
+
+			public boolean visit(AnonymousClassDeclaration anonymousClassDeclaration) {
+				ListRewrite listRewrite = rewriter.getListRewrite(anonymousClassDeclaration, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY);
+				List bodyDeclarations = anonymousClassDeclaration.bodyDeclarations();
+				final int length = bodyDeclarations.size();
+				if (length > 1) {
+					final List myCopy = new ArrayList();
+					myCopy.addAll(bodyDeclarations);
+					Collections.sort(myCopy, SortElementsOperation.this.comparator);
+					for (int i = 0; i < length; i++) {
+						listRewrite.replace((ASTNode) bodyDeclarations.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
+					}
+				}
+				return true;
+			}
+			
+			public boolean visit(TypeDeclaration typeDeclaration) {
+				ListRewrite listRewrite = rewriter.getListRewrite(typeDeclaration, TypeDeclaration.BODY_DECLARATIONS_PROPERTY);
+				List bodyDeclarations = typeDeclaration.bodyDeclarations();
+				final int length = bodyDeclarations.size();
+				if (length > 1) {
+					final List myCopy = new ArrayList();
+					myCopy.addAll(bodyDeclarations);
+					Collections.sort(myCopy, SortElementsOperation.this.comparator);
+					for (int i = 0; i < length; i++) {
+						listRewrite.replace((ASTNode) bodyDeclarations.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
+					}
+				}
+				return true;
+			}
+
+			public boolean visit(EnumDeclaration enumDeclaration) {
+				ListRewrite listRewrite = rewriter.getListRewrite(enumDeclaration, EnumDeclaration.BODY_DECLARATIONS_PROPERTY);
+				List bodyDeclarations = enumDeclaration.bodyDeclarations();
+				int length = bodyDeclarations.size();
+				if (length > 1) {
+					final List myCopy = new ArrayList();
+					myCopy.addAll(bodyDeclarations);
+					Collections.sort(myCopy, SortElementsOperation.this.comparator);
+					for (int i = 0; i < length; i++) {
+						listRewrite.replace((ASTNode) bodyDeclarations.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
+					}
+				}				
+				listRewrite = rewriter.getListRewrite(enumDeclaration, EnumDeclaration.ENUM_CONSTANTS_PROPERTY);
+				List enumConstants = enumDeclaration.enumConstants();
+				length = enumConstants.size();
+				if (length > 1) {
+					final List myCopy = new ArrayList();
+					myCopy.addAll(enumConstants);
+					Collections.sort(myCopy, SortElementsOperation.this.comparator);
+					for (int i = 0; i < length; i++) {
+						listRewrite.replace((ASTNode) enumConstants.get(i), rewriter.createMoveTarget((ASTNode) myCopy.get(i)), null);
+					}
+				}
+				return true;
+			}
+		});			
+		TextEdit edits = rewriter.rewriteAST(document, null);
+		if (needPositionsMapping) {
+			for (int i = 0, max = markers.length; i < max; i++) {
+				insert(edits, markers[i]);
+			}
+		}
+		try {
+			edits.apply(document, TextEdit.UPDATE_REGIONS);
+			generatedSource = document.get();
+			if (needPositionsMapping) {
+				for (int i= 0, max = markers.length; i < max; i++) {
+					this.positions[i]= markers[i].getOffset();
+				}
+			}
+		} catch (BadLocationException e) {
+			// ignore
+		}
+		return generatedSource;
 	}
 
 	/**
@@ -136,4 +245,47 @@
 		}
 		return JavaModelStatus.VERIFIED_OK;
 	}
+	
+	public static void insert(TextEdit parent, TextEdit edit) {
+		if (!parent.hasChildren()) {
+			parent.addChild(edit);
+			return;
+		}
+		TextEdit[] children= parent.getChildren();
+		// First dive down to find the right parent.
+		for (int i= 0; i < children.length; i++) {
+			TextEdit child= children[i];
+			if (covers(child, edit)) {
+				insert(child, edit);
+				return;
+			}
+		}
+		// We have the right parent. Now check if some of the children have to
+		// be moved under the new edit since it is covering it.
+		for (int i= children.length - 1; i >= 0; i--) {
+			TextEdit child= children[i];
+			if (covers(edit, child)) {
+				parent.removeChild(i);
+				edit.addChild(child);
+			}
+		}
+		parent.addChild(edit);
+	}
+	
+	private static boolean covers(TextEdit thisEdit, TextEdit otherEdit) {
+		if (thisEdit.getLength() == 0) {
+			return false;
+		}
+		
+		int thisOffset= thisEdit.getOffset();
+		int thisEnd= thisEdit.getExclusiveEnd();	
+		if (otherEdit.getLength() == 0) {
+			int otherOffset= otherEdit.getOffset();
+			return thisOffset <= otherOffset && otherOffset < thisEnd;
+		} else {
+			int otherOffset= otherEdit.getOffset();
+			int otherEnd= otherEdit.getExclusiveEnd();
+			return thisOffset <= otherOffset && otherEnd <= thisEnd;
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortJavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortJavaElement.java
deleted file mode 100644
index d8aae70..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortJavaElement.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core;
-
-import java.util.Arrays;
-import java.util.Hashtable;
-
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.internal.core.SortElementBuilder.SortElement;
-
-/**
- * 
- * @since 2.1
- */
-public abstract class SortJavaElement implements Comparable {
-
-	public static final int COMPILATION_UNIT = 1;
-	public static final int TYPE = 2;
-	public static final int CLASS = 4;
-	public static final int INTERFACE = 8;
-	public static final int FIELD = 16;
-	public static final int INITIALIZER = 32;
-	public static final int METHOD = 64;	
-	public static final int CONSTRUCTOR = 128;
-	public static final int MULTIPLE_FIELD = 256;
-	
-	SortElementBuilder builder;
-
-	protected static final String LINE_SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
-	public static final String CORRESPONDING_ELEMENT = "corresponding_element";  //$NON-NLS-1$
-
-	Hashtable options;
-	
-	protected int id;
-	protected int sourceStart;
-	protected int newSourceStart;
-	protected int modifiers;
-	protected String superclass;
-	protected String[] superInterfaces;
-	
-	protected String[] parametersNames;
-	protected String[] parametersTypes;
-	protected String[] thrownExceptions;
-	protected String returnType;
-	protected String name;
-	protected String type;
-	protected int fieldCounter;
-	protected SortElementBuilder.SortFieldDeclaration[] innerFields;
-	protected ASTNode[] astNodes;
-	
-	protected int sourceEnd;
-	protected int nameSourceStart;
-	protected SortElement[] children;
-	protected int children_count;
-	protected SortElement firstChildBeforeSorting;
-	protected SortElement lastChildBeforeSorting;
-	protected int declarationStart;
-	protected int declarationSourceEnd;
-	
-	SortJavaElement(SortElementBuilder builder) {
-		this.builder = builder;
-		this.options = JavaCore.getOptions();
-	} 
-	/**
-	 * @see java.lang.Comparable#compareTo(java.lang.Object)
-	 */
-	public int compareTo(Object o) {
-		return this.builder.comparator.compare(this, o);
-	}
-	
-	protected void addChild(SortElement sortElement) {
-		if (this.children_count == 0) {
-			this.children = new SortElement[3];
-		} else if (this.children_count == this.children.length) {
-			System.arraycopy(this.children, 0, this.children = new SortElement[this.children_count * 2], 0, this.children_count);
-		}
-		this.children[this.children_count++] = sortElement;
-	}
-
-	protected void closeCollections() {
-		int length = this.children_count;
-		if (length != 0 && length != this.children.length) {
-			System.arraycopy(this.children, 0, this.children= new SortElement[length], 0, length);
-		}			
-	}
-
-	abstract void display(StringBuffer buffer, int tab);
-		
-	protected void generateSource(StringBuffer buffer) {
-		this.newSourceStart = buffer.length();
-	}
-
-	abstract void mapPositions();
-	
-	public String toString(int tab) {
-		StringBuffer buffer = new StringBuffer();
-		display(buffer, tab);
-		if (this.children != null) {
-			buffer
-				.append(tab(tab))
-				.append("CHILDREN ------------------------------" + LINE_SEPARATOR); //$NON-NLS-1$
-			for (int i = 0; i < this.children_count; i++) {
-				buffer.append(this.children[i].toString(tab + 1));
-				buffer.append(LINE_SEPARATOR);
-			}
-		}
-		return buffer.toString();
-	}
-
-	protected char[] tab(int tab) {
-		char[] tabs = new char[tab];
-		Arrays.fill(tabs, '\t');
-		return tabs; 
-	}
-
-	public String toString() {
-		return toString(0);
-	}		
-
-	protected void sort() {
-		if (this.children != null) {
-			this.firstChildBeforeSorting = children[0];
-			this.lastChildBeforeSorting = children[this.children_count - 1];
-			switch(this.id) {
-				case CLASS | TYPE :
-				case INTERFACE | TYPE :
-				case COMPILATION_UNIT :		
-					this.astNodes = convertChildren();
-					Arrays.sort(astNodes, this.builder.comparator);
-			}
-			for (int i = 0, max = this.children_count; i < max; i++) {
-				children[i].sort();
-			} 
-		}
-	}
-	
-	private ASTNode[] convertChildren() {
-		ASTNode[] convertedNodes = new ASTNode[this.children_count];
-		for (int i = 0, max = this.children_count; i < max; i++) {
-			SortElementBuilder.SortElement currentElement = this.children[i];
-			ASTNode newNode = currentElement.convert();
-			newNode.setProperty(CORRESPONDING_ELEMENT, currentElement);
-			convertedNodes[i] = newNode;
-		}
-		return convertedNodes;
-	}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java
index 34cc073..46407d6 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceAnnotationMethodInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java
index 07468d4..1fe69f5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceConstructorInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
index 746d179..33af54e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,8 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
-import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 
 /**
  * @see IField
@@ -33,13 +34,12 @@
 	if (!(o instanceof SourceField)) return false;
 	return super.equals(o);
 }
-/**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	return (node.getNodeType() == IDOMNode.FIELD) && super.equalsDOMNode(node);
+public ASTNode findNode(org.eclipse.jdt.core.dom.CompilationUnit ast) {
+	// For field declarations, a variable declaration fragment is returned
+	// Return the FieldDeclaration instead
+	ASTNode node = super.findNode(ast);
+	if (node == null) return null;
+	return node.getParent();
 }
 /**
  * @see IField
@@ -47,11 +47,12 @@
 public Object getConstant() throws JavaModelException {
 	Object constant = null;	
 	SourceFieldElementInfo info = (SourceFieldElementInfo) getElementInfo();
-	if (info.initializationSource == null) {
+	final char[] constantSourceChars = info.initializationSource;
+	if (constantSourceChars == null) {
 		return null;
 	}
 			
-	String constantSource = new String(info.initializationSource);
+	String constantSource = new String(constantSourceChars);
 	String signature = info.getTypeSignature();
 	if (signature.equals(Signature.SIG_INT)) {
 		constant = new Integer(constantSource);
@@ -62,7 +63,10 @@
 	} else if (signature.equals(Signature.SIG_BOOLEAN)) {
 		constant = Boolean.valueOf(constantSource);
 	} else if (signature.equals(Signature.SIG_CHAR)) {
-		constant = new Character(constantSource.charAt(0));
+		if (constantSourceChars.length != 3) {
+			return null;
+		}
+		constant = new Character(constantSourceChars[1]);
 	} else if (signature.equals(Signature.SIG_DOUBLE)) {
 		constant = new Double(constantSource);
 	} else if (signature.equals(Signature.SIG_FLOAT)) {
@@ -89,6 +93,17 @@
 public int getElementType() {
 	return FIELD;
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#getKey()
+ */
+public String getKey() {
+	try {
+		return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
 /**
  * @see JavaElement#getHandleMemento()
  */
@@ -113,6 +128,22 @@
 	SourceFieldElementInfo info = (SourceFieldElementInfo) getElementInfo();
 	return info.getTypeSignature();
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isEnumConstant()
+ */public boolean isEnumConstant() throws JavaModelException {
+	return Flags.isEnum(getFlags());
+}
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IField#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedSourceField(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
 /**
  * @private Debugging purposes
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java
index de0c5bb..d3d5f3d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceFieldElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,8 +19,6 @@
 
 public class SourceFieldElementInfo extends MemberElementInfo implements ISourceField {
 	
-	protected char[] fieldName;
-
 	/**
 	 * The type name of this field.
 	 */
@@ -38,9 +36,6 @@
 public char[] getInitializationSource() {
 	return this.initializationSource;
 }
-public char[] getName() {
-	return this.fieldName;
-}
 /**
  * Returns the type name of the field.
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
index a4013a0..23bf465 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -1049,7 +1049,8 @@
 				}
 			}
 			boolean doFullParse = hasToRetrieveSourceRangesForLocalClass(fullName);
-			parser = new SourceElementParser(this, factory, new CompilerOptions(this.options), doFullParse);
+			parser = new SourceElementParser(this, factory, new CompilerOptions(this.options), doFullParse, true/*optimize string literals*/);
+			parser.javadocParser.checkDocComment = false; // disable javadoc parsing
 			IJavaElement javaElement = this.binaryType.getCompilationUnit();
 			if (javaElement == null) javaElement = this.binaryType.getParent();
 			parser.parseCompilationUnit(
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
index db83ef6..2730f34 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,7 +17,7 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.core.jdom.*;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -31,15 +31,15 @@
 	 * to perform equality test. <code>null</code> indicates no
 	 * parameters.
 	 */
-	protected String[] fParameterTypes;
+	protected String[] parameterTypes;
 
 protected SourceMethod(JavaElement parent, String name, String[] parameterTypes) {
 	super(parent, name);
 	Assert.isTrue(name.indexOf('.') == -1);
 	if (parameterTypes == null) {
-		fParameterTypes= CharOperation.NO_STRINGS;
+		this.parameterTypes= CharOperation.NO_STRINGS;
 	} else {
-		fParameterTypes= parameterTypes;
+		this.parameterTypes= parameterTypes;
 	}
 }
 protected void closing(Object info) throws JavaModelException {
@@ -52,31 +52,7 @@
 }
 public boolean equals(Object o) {
 	if (!(o instanceof SourceMethod)) return false;
-	return super.equals(o) && Util.equalArraysOrNull(fParameterTypes, ((SourceMethod)o).fParameterTypes);
-}
-/**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	if (node.getNodeType() == IDOMNode.METHOD) {
-		try {
-			IDOMMethod m = (IDOMMethod)node;
-			if (isConstructor()) {
-				return 
-					(m.isConstructor() || m.getName().equals(this.getElementName()) /* case of a constructor that is being renamed */) 
-						&& signatureEquals(m);
-			} else {
-				return super.equalsDOMNode(node) && signatureEquals(m);
-			}
-		} catch (JavaModelException e) {
-			return false;
-		}
-	} else {
-		return false;
-	}
-
+	return super.equals(o) && Util.equalArraysOrNull(this.parameterTypes, ((SourceMethod)o).parameterTypes);
 }
 /**
  * @see IJavaElement
@@ -100,9 +76,9 @@
 	char delimiter = getHandleMementoDelimiter();
 	buff.append(delimiter);
 	escapeMementoName(buff, getElementName());
-	for (int i = 0; i < fParameterTypes.length; i++) {
+	for (int i = 0; i < this.parameterTypes.length; i++) {
 		buff.append(delimiter);
-		escapeMementoName(buff, fParameterTypes[i]);
+		escapeMementoName(buff, this.parameterTypes[i]);
 	}
 	if (this.occurrenceCount > 1) {
 		buff.append(JEM_COUNT);
@@ -115,11 +91,22 @@
 protected char getHandleMementoDelimiter() {
 	return JavaElement.JEM_METHOD;
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IMethod#getKey()
+ */
+public String getKey() {
+	try {
+		return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
 /**
  * @see IMethod
  */
 public int getNumberOfParameters() {
-	return fParameterTypes == null ? 0 : fParameterTypes.length;
+	return this.parameterTypes == null ? 0 : this.parameterTypes.length;
 }
 /**
  * @see IMethod
@@ -133,7 +120,7 @@
  * @see IMethod
  */
 public String[] getParameterTypes() {
-	return fParameterTypes;
+	return this.parameterTypes;
 }
 
 public ITypeParameter getTypeParameter(String typeParameterName) {
@@ -181,7 +168,7 @@
 		if (cu.isPrimary()) return this;
 	}
 	IJavaElement primaryParent = this.parent.getPrimaryElement(false);
-	return ((IType)primaryParent).getMethod(this.name, fParameterTypes);
+	return ((IType)primaryParent).getMethod(this.name, this.parameterTypes);
 }
 /**
  * @see IMethod
@@ -195,15 +182,15 @@
  */
 public String getSignature() throws JavaModelException {
 	SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
-	return info.getSignature();
+	return Signature.createMethodSignature(this.parameterTypes, Signature.createTypeSignature(info.getReturnTypeName(), false));
 }
 /**
  * @see org.eclipse.jdt.internal.core.JavaElement#hashCode()
  */
 public int hashCode() {
    int hash = super.hashCode();
-	for (int i = 0, length = fParameterTypes.length; i < length; i++) {
-	    hash = Util.combineHashCodes(hash, fParameterTypes[i].hashCode());
+	for (int i = 0, length = this.parameterTypes.length; i < length; i++) {
+	    hash = Util.combineHashCodes(hash, this.parameterTypes[i].hashCode());
 	}
 	return hash;
 }
@@ -220,7 +207,12 @@
 public boolean isMainMethod() throws JavaModelException {
 	return this.isMainMethod(this);
 }
-
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IMethod#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
 /**
  * @see IMethod#isSimilar(IMethod)
  */
@@ -238,11 +230,10 @@
 
 	StringBuffer buffer = new StringBuffer(super.readableName());
 	buffer.append('(');
-	String[] parameterTypes = this.getParameterTypes();
 	int length;
-	if (parameterTypes != null && (length = parameterTypes.length) > 0) {
+	if (this.parameterTypes != null && (length = this.parameterTypes.length) > 0) {
 		for (int i = 0; i < length; i++) {
-			buffer.append(Signature.toString(parameterTypes[i]));
+			buffer.append(Signature.toString(this.parameterTypes[i]));
 			if (i < length - 1) {
 				buffer.append(", "); //$NON-NLS-1$
 			}
@@ -251,41 +242,10 @@
 	buffer.append(')');
 	return buffer.toString();
 }
-/**
- * Returns <code>true</code> if the signature of this <code>SourceMethod</code> matches that of the given
- * <code>IDOMMethod</code>, otherwise <code>false</code>. 
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean signatureEquals(IDOMMethod method) {
-	String[] otherTypes= method.getParameterTypes();
-	String[] types= getParameterTypes();
-	boolean ok= true;
-
-	// ensure the number of parameters match
-	if (otherTypes == null || otherTypes.length == 0) {
-		ok= (types == null || types.length == 0);
-	} else if (types != null) {
-		ok= (otherTypes.length == types.length);
-	} else {
-		return false;
-	}
-
-	// ensure the parameter type signatures match
-	if (ok) {
-		if (types != null) {
-			int i;
-			for (i= 0; i < types.length; i++) {
-				String otherType= Signature.createTypeSignature(otherTypes[i].toCharArray(), false);
-				if (!types[i].equals(otherType)) {
-					ok= false;
-					break;
-				}
-			}
-		}
-	}
-
-	return ok;
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedSourceMethod(this.parent, this.name, this.parameterTypes, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
 }
 /**
  * @private Debugging purposes
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java
index e35c41f..5230b2f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.env.ISourceMethod;
 
@@ -21,8 +20,6 @@
  */
 public abstract class SourceMethodElementInfo extends MemberElementInfo implements ISourceMethod {
 	
-	protected char[] selector;
-
 	/**
 	 * For a source method (that is, a method contained in a compilation unit)
 	 * this is a collection of the names of the parameters for this method,
@@ -34,15 +31,6 @@
 	protected char[][] argumentNames;
 
 	/**
-	 * Collection of type names for the arguments in this
-	 * method, in the order they are declared. This is an empty
-	 * array for a method with no arguments. A name is a simple
-	 * name or a qualified, dot separated name.
-	 * For example, Hashtable or java.util.Hashtable.
-	 */
-	protected char[][] argumentTypeNames;
-
-	/**
 	 * A collection of type names of the exceptions this
 	 * method throws, or an empty collection if this method
 	 * does not declare to throw any exceptions. A name is a simple
@@ -59,25 +47,11 @@
 public char[][] getArgumentNames() {
 	return this.argumentNames;
 }
-public char[][] getArgumentTypeNames() {
-	return this.argumentTypeNames;
-}
 public char[][] getExceptionTypeNames() {
 	return this.exceptionTypes;
 }
 public abstract char[] getReturnTypeName();
 
-public char[] getSelector() {
-	return this.selector;
-}
-protected String getSignature() {
-
-	String[] paramSignatures = new String[this.argumentTypeNames.length];
-	for (int i = 0; i < this.argumentTypeNames.length; ++i) {
-		paramSignatures[i] = Signature.createTypeSignature(this.argumentTypeNames[i], false);
-	}
-	return Signature.createMethodSignature(paramSignatures, Signature.createTypeSignature(getReturnTypeName(), false));
-}
 public char[][][] getTypeParameterBounds() {
 	int length = this.typeParameters.length;
 	char[][][] typeParameterBounds = new char[length][][];
@@ -105,9 +79,6 @@
 protected void setArgumentNames(char[][] names) {
 	this.argumentNames = names;
 }
-protected void setArgumentTypeNames(char[][] types) {
-	this.argumentTypeNames = types;
-}
 protected void setExceptionTypeNames(char[][] types) {
 	this.exceptionTypes = types;
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java
index 484484a..e4c54c2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRange.java
index 24cb1b9..7332b9c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRange.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRange.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java
index eec3db3..daff756 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElement.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,8 +23,11 @@
 import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.ISourceReference;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.internal.core.util.DOMFinder;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * Abstract class for Java elements which implement ISourceReference.
@@ -60,7 +63,7 @@
  */
 public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (container == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullContainer); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] containers= new IJavaElement[] {container};
@@ -86,6 +89,19 @@
 	return this.occurrenceCount == ((SourceRefElement)o).occurrenceCount &&
 			super.equals(o);
 }
+/**
+ * Returns the <code>ASTNode</code> that corresponds to this <code>JavaElement</code>
+ * or <code>null</code> if there is no corresponding node.
+ */
+public ASTNode findNode(CompilationUnit ast) {
+	DOMFinder finder = new DOMFinder(ast, this, false);
+	try {
+		return finder.search();
+	} catch (JavaModelException e) {
+		// receiver doesn't exist
+		return null;
+	}
+}
 /*
  * @see JavaElement#generateInfos
  */
@@ -221,7 +237,7 @@
  */
 public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (container == null) {
-		throw new IllegalArgumentException(Util.bind("operation.nullContainer")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.operation_nullContainer); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] containers= new IJavaElement[] {container};
@@ -240,7 +256,7 @@
  */
 public void rename(String newName, boolean force, IProgressMonitor monitor) throws JavaModelException {
 	if (newName == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullName); 
 	}
 	IJavaElement[] elements= new IJavaElement[] {this};
 	IJavaElement[] dests= new IJavaElement[] {this.getParent()};
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java
index b4f7bc1..fe09baf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceRefElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
index 13e757a..4f72a4d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,16 +17,16 @@
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.*;
 import org.eclipse.jdt.core.compiler.IProblem;
-import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.core.search.SearchEngine;
 import org.eclipse.jdt.internal.codeassist.CompletionEngine;
 import org.eclipse.jdt.internal.codeassist.ISelectionRequestor;
 import org.eclipse.jdt.internal.codeassist.SelectionEngine;
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.env.ISourceType;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy;
 import org.eclipse.jdt.internal.core.util.MementoTokenizer;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * Handle for a source type. Info object is a SourceTypeElementInfo.
@@ -40,7 +40,7 @@
 	
 protected SourceType(JavaElement parent, String name) {
 	super(parent, name);
-	Assert.isTrue(name.indexOf('.') == -1, Util.bind("sourcetype.invalidName", name)); //$NON-NLS-1$
+	Assert.isTrue(name.indexOf('.') == -1, Messages.bind(Messages.sourcetype_invalidName, name)); 
 }
 protected void closing(Object info) throws JavaModelException {
 	super.closing(info);
@@ -104,8 +104,10 @@
 	} else {
 		engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
 	}
-	if (NameLookup.VERBOSE)
+	if (NameLookup.VERBOSE) {
 		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
 }
 /**
  * @see IType
@@ -155,14 +157,6 @@
 	if (!(o instanceof SourceType)) return false;
 	return super.equals(o);
 }
-/**
- * @see JavaElement#equalsDOMNode
- * @deprecated JDOM is obsolete
- */
-// TODO - JDOM - remove once model ported off of JDOM
-protected boolean equalsDOMNode(IDOMNode node) {
-	return (node.getNodeType() == IDOMNode.TYPE) && super.equalsDOMNode(node);
-}
 /*
  * @see IType
  */
@@ -337,6 +331,17 @@
 	list.toArray(array);
 	return array;
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IType#getKey()
+ */
+public String getKey() {
+	try {
+		return getKey(this, org.eclipse.jdt.internal.compiler.lookup.Binding.USE_ACCESS_FLAGS_IN_BINDING_KEY/*with access flags*/, false/*don't open*/);
+	} catch (JavaModelException e) {
+		// happen only if force open is true
+		return null;
+	}
+}
 /**
  * @see IType#getMethod
  */
@@ -430,7 +435,14 @@
 public String[] getSuperInterfaceTypeSignatures() throws JavaModelException {
 	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
 	char[][] names= info.getInterfaceNames();
-	return CharOperation.toStrings(names);
+	if (names == null) {
+		return CharOperation.NO_STRINGS;
+	}
+	String[] strings= new String[names.length];
+	for (int i= 0; i < names.length; i++) {
+		strings[i]= new String(Signature.createTypeSignature(names[i], false));
+	}
+	return strings;
 }
 
 public ITypeParameter[] getTypeParameters() throws JavaModelException {
@@ -438,17 +450,9 @@
 	return info.typeParameters;
 }
 
-// Get type parameter names
-// TODO (frederic) see if this method needs to be added to API
-public char[][] getTypeParameterNames() throws JavaModelException {
-	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
-	return info.getTypeParameterNames();
-}
-
 /**
  * @see IType#getTypeParameterSignatures()
  * @since 3.0
- * @deprecated
  */
 public String[] getTypeParameterSignatures() throws JavaModelException {
 	ITypeParameter[] typeParameters = getTypeParameters();
@@ -519,8 +523,8 @@
  * @see IType
  */
 public boolean isClass() throws JavaModelException {
-	// TODO (jerome) - isClass should only return true for classes other than enum classes
-	return !isInterface();
+	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
+	return info.getKind() == IGenericType.CLASS_DECL;
 }
 
 /**
@@ -537,7 +541,12 @@
  */
 public boolean isInterface() throws JavaModelException {
 	SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo();
-	return info.getKind() == IGenericType.INTERFACE_DECL;
+	switch (info.getKind()) {
+		case IGenericType.INTERFACE_DECL:
+		case IGenericType.ANNOTATION_TYPE_DECL: // annotation is interface too
+			return true;
+	}
+	return false;
 }
 
 /**
@@ -561,6 +570,12 @@
 public boolean isMember() {
 	return getDeclaringType() != null;
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.core.IType#isResolved()
+ */
+public boolean isResolved() {
+	return false;
+}
 /**
  * @see IType
  */
@@ -667,7 +682,7 @@
  */
 public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
 	if (project == null) {
-		throw new IllegalArgumentException(Util.bind("hierarchy.nullProject")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.hierarchy_nullProject); 
 	}
 	ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
 	ICompilationUnit[] projectWCs = null;
@@ -744,6 +759,11 @@
 	op.runOperation(monitor);
 	return op.getResult();	
 }
+public JavaElement resolved(Binding binding) {
+	SourceRefElement resolvedHandle = new ResolvedSourceType(this.parent, this.name, new String(binding.computeUniqueKey()));
+	resolvedHandle.occurrenceCount = this.occurrenceCount;
+	return resolvedHandle;
+}
 /**
  * @see IType#resolveType(String)
  */
@@ -760,7 +780,8 @@
 
 	class TypeResolveRequestor implements ISelectionRequestor {
 		String[][] answers = null;
-		void acceptType(String[] answer){
+		public void acceptType(char[] packageName, char[] tName, int modifiers, boolean isDeclaration, char[] uniqueKey, int start, int end) {
+			String[] answer = new String[]  {new String(packageName), new String(tName) };
 			if (this.answers == null) {
 				this.answers = new String[][]{ answer };
 			} else {
@@ -770,19 +791,6 @@
 				this.answers[length] = answer;
 			}
 		}
-		public void acceptAnnotation(char[] packageName, char[] annotationName, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-			acceptType(new String[]  { new String(packageName), new String(annotationName) });
-		}
-		public void acceptClass(char[] packageName, char[] className, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-			acceptType(new String[]  { new String(packageName), new String(className) });
-		}
-		public void acceptEnum(char[] packageName, char[] enumName, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-			acceptType(new String[]  { new String(packageName), new String(enumName) });
-		}
-		public void acceptInterface(char[] packageName, char[] interfaceName, boolean isDeclaration, char[] genericTypeSignature, int start, int end) {
-			acceptType(new String[]  { new String(packageName), new String(interfaceName) });
-		}
-
 		public void acceptError(IProblem error) {
 			// ignore
 		}
@@ -815,8 +823,10 @@
 	}
 		
 	engine.selectType(info, typeName.toCharArray(), topLevelInfos, false);
-	if (NameLookup.VERBOSE)
+	if (NameLookup.VERBOSE) {
 		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+		System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms");  //$NON-NLS-1$ //$NON-NLS-2$
+	}
 	return requestor.answers;
 }
 /**
@@ -845,7 +855,11 @@
 		}
 	} else {
 		try {
-			if (this.isInterface()) {
+			if (this.isEnum()) {
+				buffer.append("enum "); //$NON-NLS-1$
+			} else if (this.isAnnotation()) {
+				buffer.append("@interface "); //$NON-NLS-1$
+			} else if (this.isInterface()) {
 				buffer.append("interface "); //$NON-NLS-1$
 			} else {
 				buffer.append("class "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
index 6af4f13..ec9777a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java
@@ -1,17 +1,16 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
 import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.IImportDeclaration;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
@@ -49,21 +48,6 @@
 	protected char[][] superInterfaceNames;
 	
 	/**
-	 * The name of the source file this type is declared in.
-	 */
-	protected char[] sourceFileName;
-
-	/**
-	 * The name of the package this type is contained in.
-	 */
-	protected char[] packageName;
-
-	/**
-	 * The infos of the imports in this type's compilation unit
-	 */
-	private ISourceImport[] imports;
-	
-	/**
 	 * Backpointer to my type handle - useful for translation
 	 * from info to handle.
 	 */
@@ -126,7 +110,7 @@
  * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
  */
 public char[] getFileName() {
-	return this.sourceFileName;
+	return this.handle.getPath().toString().toCharArray();
 }
 /**
  * Returns the handle for this type info
@@ -134,29 +118,6 @@
 public IType getHandle() {
 	return this.handle;
 }
-/**
- * @see ISourceType
- */
-public ISourceImport[] getImports() {
-	if (this.imports == null) {
-		try {
-			IImportDeclaration[] importDeclarations = this.handle.getCompilationUnit().getImports();
-			int length = importDeclarations.length;
-			if (length == 0) {
-				this.imports = NO_IMPORTS;
-			} else {
-				ISourceImport[] sourceImports = new ISourceImport[length];
-				for (int i = 0; i < length; i++) {
-					sourceImports[i] = (ImportDeclarationElementInfo)((ImportDeclaration)importDeclarations[i]).getElementInfo();
-				}
-				this.imports = sourceImports; // only commit at the end, once completed (bug 36854)
-			}
-		} catch (JavaModelException e) {
-			this.imports = NO_IMPORTS;
-		}
-	}
-	return this.imports;
-}
 /*
  * Returns the InitializerElementInfos for this type.
  * Returns an empty array if none.
@@ -276,12 +237,6 @@
 /**
  * @see ISourceType
  */
-public char[] getPackageName() {
-	return this.packageName;
-}
-/**
- * @see ISourceType
- */
 public char[] getSuperclassName() {
 	if (this.handle.getElementName().length() == 0) { // if anonymous type
 		char[][] interfaceNames = this.superInterfaceNames;	
@@ -326,18 +281,6 @@
 	this.handle = handle;
 }
 /**
- * Sets the name of the package this type is declared in.
- */
-protected void setPackageName(char[] name) {
-	this.packageName= name;
-}
-/**
- * Sets the name of the source file this type is declared in.
- */
-protected void setSourceFileName(char[] name) {
-	this.sourceFileName= name;
-}
-/**
  * Sets the (unqualified) name of this type's superclass
  */
 protected void setSuperclassName(char[] superclassName) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
index 8b3fa07..a1b861e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java
index 840c667..75b0422 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeParameterElementInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
index 011b6e2..a4d86f2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeVector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
index c958abe..481781c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibrary.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,7 +23,7 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -129,15 +129,15 @@
 			DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 			cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
 		} catch (SAXException e) {
-			throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+			throw new IOException(Messages.file_badFormat); 
 		} catch (ParserConfigurationException e) {
-			throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+			throw new IOException(Messages.file_badFormat); 
 		} finally {
 			reader.close();
 		}
 		
 		if (!cpElement.getNodeName().equalsIgnoreCase(TAG_USERLIBRARY)) { //$NON-NLS-1$
-			throw new IOException(Util.bind("file.badFormat")); //$NON-NLS-1$
+			throw new IOException(Messages.file_badFormat); 
 		}
 		// String version= cpElement.getAttribute(TAG_VERSION);
 		// in case we update the format: add code to read older versions
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java
index 4069ac9..c5e9b89 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java
index 2920dcb..a516a38 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryClasspathContainerInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java
index abe2f22..d53df3b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -124,7 +124,7 @@
 		if (userLibraries == null) {
 			userLibraries= new HashMap();
 			// load variables and containers from preferences into cache
-			IEclipsePreferences instancePreferences = JavaCore.getInstancePreferences();
+			IEclipsePreferences instancePreferences = JavaModelManager.getJavaModelManager().getInstancePreferences();
 			instancePreferences.addPreferenceChangeListener(listener);
 
 			// only get variable from preferences not set to their default
@@ -143,7 +143,7 @@
 					}
 				}
 			} catch (BackingStoreException e) {
-				// TODO (frederic) see if it's necessary to report this exception
+				// nothing to do in this case
 			}
 		}
 		return userLibraries;
@@ -182,7 +182,7 @@
 			}
 		}
 		
-		IEclipsePreferences instancePreferences = JavaCore.getInstancePreferences();
+		IEclipsePreferences instancePreferences = JavaModelManager.getJavaModelManager().getInstancePreferences();
 		String containerKey = CP_USERLIBRARY_PREFERENCES_PREFIX+name;
 		String containerString = CP_ENTRY_IGNORE;
 		if (library != null) {
@@ -194,13 +194,12 @@
 		}
 		instancePreferences.removePreferenceChangeListener(listener);
 		try {
-			JavaCore.getDefaultPreferences().put(containerKey, CP_ENTRY_IGNORE); // TODO (frederic) verify if this is really necessary...
 			instancePreferences.put(containerKey, containerString);
 			if (save) {
 				try {
 					instancePreferences.flush();
 				} catch (BackingStoreException e) {
-					// TODO (frederic) see if it's necessary to report this exception
+					// nothing to do in this case
 				}
 			}
 			if (rebind) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
index 94e4a3f..7294367 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/XMLWriter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -56,12 +56,12 @@
 	private int tab;
 	public XMLWriter(Writer writer) {
 		super(writer);
-		tab= 0;
+		this.tab= 0;
 		println(XML_VERSION);
 	}
 	public void endTag(String name, boolean insertTab) {
-		tab--;
-		printTag('/' + name, null, insertTab, true, false);
+		this.tab --;
+		printTag('/' + name, null/*no parameters*/, insertTab, true/*insert new line*/, false/*don't close tag*/);
 	}
 	private void printTabulation() {
 		for (int i= 0; i < tab; i++)
@@ -94,9 +94,12 @@
 		} else {
 			print(sb.toString());
 		}
+		if (parameters != null && !closeTag)
+			this.tab++;
+
 	}
 	public void startTag(String name, boolean insertTab) {
-		printTag(name, null, insertTab, true, false);
-		tab++;
+		printTag(name, null/*no parameters*/, insertTab, true/*insert new line*/, false/*don't close tag*/);
+		this.tab++;
 	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java
index 9f25413..7d11742 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbortIncrementalBuildException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
index 24e3585..99202df 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,8 +19,10 @@
 import org.eclipse.jdt.internal.compiler.*;
 import org.eclipse.jdt.internal.compiler.ClassFile;
 import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.problem.*;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 import java.io.*;
@@ -49,6 +51,19 @@
 private boolean inCompiler;
 
 public static int MAX_AT_ONCE = 1000;
+public final static String[] JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES = {
+					IMarker.MESSAGE, 
+					IMarker.SEVERITY, 
+					IJavaModelMarker.ID, 
+					IMarker.CHAR_START, 
+					IMarker.CHAR_END, 
+					IMarker.LINE_NUMBER, 
+					IJavaModelMarker.ARGUMENTS};
+public final static Integer S_ERROR = new Integer(IMarker.SEVERITY_ERROR);
+public final static Integer S_WARNING = new Integer(IMarker.SEVERITY_WARNING);
+public final static Integer P_HIGH = new Integer(IMarker.PRIORITY_HIGH);
+public final static Integer P_NORMAL = new Integer(IMarker.PRIORITY_NORMAL);
+public final static Integer P_LOW = new Integer(IMarker.PRIORITY_LOW);
 
 protected AbstractImageBuilder(JavaBuilder javaBuilder) {
 	this.javaBuilder = javaBuilder;
@@ -89,6 +104,8 @@
 			if (!problemSourceFiles.contains(compilationUnit))
 				problemSourceFiles.add(compilationUnit);
 
+		IType mainType = null;
+		String mainTypeName = null;
 		String typeLocator = compilationUnit.typeLocator();
 		ClassFile[] classFiles = result.getClassFiles();
 		int length = classFiles.length;
@@ -112,13 +129,21 @@
 					if (duplicateTypeNames == null)
 						duplicateTypeNames = new ArrayList();
 					duplicateTypeNames.add(compoundName);
-					IType type = null;
-					try {
-						type = javaBuilder.javaProject.findType(qualifiedTypeName.replace('/', '.'));
-					} catch (JavaModelException e) {
-						// ignore
+					if (mainType == null)
+						try {
+							mainTypeName = compilationUnit.initialTypeName; // slash separated qualified name "p1/p1/A"
+							mainType = javaBuilder.javaProject.findType(mainTypeName.replace('/', '.'));
+						} catch (JavaModelException e) {
+							// ignore
+						}
+					IType type;
+					if (qualifiedTypeName.equals(mainTypeName))
+						type = mainType;
+					else {
+						String simpleName = qualifiedTypeName.substring(qualifiedTypeName.lastIndexOf('/')+1);
+						type = mainType == null ? null : mainType.getCompilationUnit().getType(simpleName);
 					}
-					createProblemFor(compilationUnit.resource, type, Util.bind("build.duplicateClassFile", new String(typeName)), JavaCore.ERROR); //$NON-NLS-1$
+					createProblemFor(compilationUnit.resource, type, Messages.bind(Messages.build_duplicateClassFile, new String(typeName)), JavaCore.ERROR); 
 					continue;
 				}
 				newState.recordLocatorForType(qualifiedTypeName, typeLocator);
@@ -128,9 +153,9 @@
 			} catch (CoreException e) {
 				Util.log(e, "JavaBuilder handling CoreException"); //$NON-NLS-1$
 				if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS)
-					createProblemFor(compilationUnit.resource, null, Util.bind("build.classFileCollision", e.getMessage()), JavaCore.ERROR); //$NON-NLS-1$
+					createProblemFor(compilationUnit.resource, null, Messages.bind(Messages.build_classFileCollision, e.getMessage()), JavaCore.ERROR); 
 				else
-					createProblemFor(compilationUnit.resource, null, Util.bind("build.inconsistentClassFile"), JavaCore.ERROR); //$NON-NLS-1$
+					createProblemFor(compilationUnit.resource, null, Messages.build_inconsistentClassFile, JavaCore.ERROR); 
 			}
 		}
 		finishedWith(typeLocator, result, compilationUnit.getMainTypeName(), definedTypeNames, duplicateTypeNames);
@@ -281,16 +306,30 @@
 }
 
 protected Compiler newCompiler() {
+	// disable entire javadoc support if not interested in diagnostics
+	Map projectOptions = javaBuilder.javaProject.getOptions(true);
+	String option = (String) projectOptions.get(JavaCore.COMPILER_PB_INVALID_JAVADOC);
+	if (option == null || option.equals(JavaCore.IGNORE)) { // TODO (frederic) see why option is null sometimes while running model tests!?
+		option = (String) projectOptions.get(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS);
+		if (option == null || option.equals(JavaCore.IGNORE)) {
+			option = (String) projectOptions.get(JavaCore.COMPILER_PB_MISSING_JAVADOC_COMMENTS);
+			if (option == null || option.equals(JavaCore.IGNORE))
+				projectOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.DISABLED);
+		}
+	}
+	
 	// called once when the builder is initialized... can override if needed
 	Compiler newCompiler = new Compiler(
 		nameEnvironment,
 		DefaultErrorHandlingPolicies.proceedWithAllProblems(),
-		javaBuilder.javaProject.getOptions(true),
+		projectOptions,
 		this,
 		ProblemFactory.getProblemFactory(Locale.getDefault()));
-	// enable the compiler reference info support
-	newCompiler.options.produceReferenceInfo = true;
+	CompilerOptions options = newCompiler.options;
 
+	// enable the compiler reference info support
+	options.produceReferenceInfo = true;
+	
 	org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment env = newCompiler.lookupEnvironment;
 	synchronized (env) {
 		// enable shared byte[]'s used by ClassFile to avoid allocating MBs during a build
@@ -341,17 +380,10 @@
 		if (id != IProblem.Task) {
 			IMarker marker = resource.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
 			marker.setAttributes(
-				new String[] {
-					IMarker.MESSAGE, 
-					IMarker.SEVERITY, 
-					IJavaModelMarker.ID, 
-					IMarker.CHAR_START, 
-					IMarker.CHAR_END, 
-					IMarker.LINE_NUMBER, 
-					IJavaModelMarker.ARGUMENTS},
+				JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES,
 				new Object[] { 
 					problem.getMessage(),
-					new Integer(problem.isError() ? IMarker.SEVERITY_ERROR : IMarker.SEVERITY_WARNING), 
+					problem.isError() ? S_ERROR : S_WARNING, 
 					new Integer(id),
 					new Integer(problem.getSourceStart()),
 					new Integer(problem.getSourceEnd() + 1),
@@ -391,30 +423,22 @@
 		IProblem task = tasks[i];
 		if (task.getID() == IProblem.Task) {
 			IMarker marker = resource.createMarker(IJavaModelMarker.TASK_MARKER);
-			int priority = IMarker.PRIORITY_NORMAL;
+			Integer priority = P_NORMAL;
 			String compilerPriority = task.getArguments()[2];
 			if (JavaCore.COMPILER_TASK_PRIORITY_HIGH.equals(compilerPriority))
-				priority = IMarker.PRIORITY_HIGH;
+				priority = P_HIGH;
 			else if (JavaCore.COMPILER_TASK_PRIORITY_LOW.equals(compilerPriority))
-				priority = IMarker.PRIORITY_LOW;
+				priority = P_LOW;
 			marker.setAttributes(
-				new String[] {
-					IMarker.MESSAGE, 
-					IMarker.PRIORITY, 
-					IMarker.DONE, 
-					IMarker.CHAR_START, 
-					IMarker.CHAR_END, 
-					IMarker.LINE_NUMBER,
-					IMarker.USER_EDITABLE, 
-				}, 
+				JAVA_PROBLEM_MARKER_ATTRIBUTE_NAMES,
 				new Object[] { 
 					task.getMessage(),
-					new Integer(priority),
+					priority,
 					org.eclipse.jdt.internal.compiler.util.Util.toBoolean(false),
 					new Integer(task.getSourceStart()),
 					new Integer(task.getSourceEnd() + 1),
 					new Integer(task.getSourceLineNumber()),
-					new Boolean(false),
+					Boolean.FALSE,
 				});
 		}
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java
index 6ac6116..6adf478 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AdditionalTypeCollection.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
index 156a194..b623720 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BatchImageBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,6 +14,7 @@
 import org.eclipse.core.runtime.*;
 
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 import java.util.*;
@@ -30,12 +31,12 @@
 		System.out.println("FULL build"); //$NON-NLS-1$
 
 	try {
-		notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$
+		notifier.subTask(Messages.build_cleaningOutput); 
 		JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject);
 		cleanOutputFolders(true);
 		notifier.updateProgressDelta(0.1f);
 
-		notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
+		notifier.subTask(Messages.build_analyzingSources); 
 		ArrayList sourceFiles = new ArrayList(33);
 		addAllSourceFiles(sourceFiles);
 		notifier.updateProgressDelta(0.15f);
@@ -103,7 +104,7 @@
 	if (deleteAll) {
 		ArrayList visited = new ArrayList(sourceLocations.length);
 		for (int i = 0, l = sourceLocations.length; i < l; i++) {
-			notifier.subTask(Util.bind("build.cleaningOutput")); //$NON-NLS-1$
+			notifier.subTask(Messages.build_cleaningOutput); 
 			ClasspathMultiDirectory sourceLocation = sourceLocations[i];
 			if (sourceLocation.hasIndependentOutputFolder) {
 				IContainer outputFolder = sourceLocation.binaryFolder;
@@ -188,7 +189,7 @@
 	// When, if ever, does a builder need to copy resources files (not .java or .class) into the output folder?
 	// If we wipe the output folder at the beginning of the build then all 'extra' resources must be copied to the output folder.
 
-	notifier.subTask(Util.bind("build.copyingResources")); //$NON-NLS-1$
+	notifier.subTask(Messages.build_copyingResources); 
 	final int segmentCount = sourceLocation.sourceFolder.getFullPath().segmentCount();
 	final char[][] exclusionPatterns = sourceLocation.exclusionPatterns;
 	final char[][] inclusionPatterns = sourceLocation.inclusionPatterns;
@@ -218,7 +219,7 @@
 								createProblemFor(
 									resource,
 									null,
-									Util.bind("build.duplicateResource", id), //$NON-NLS-1$
+									Messages.bind(Messages.build_duplicateResource, (new String[] {id})), 
 									javaBuilder.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_DUPLICATE_RESOURCE, true));
 								return false;
 							}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java
index 60662bb..8d661fb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/BuildNotifier.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,7 @@
 
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 public class BuildNotifier {
 
@@ -58,7 +58,7 @@
  * Notification before a compile that a unit is about to be compiled.
  */
 public void aboutToCompile(SourceFile unit) {
-	String message = Util.bind("build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
+	String message = Messages.bind(Messages.build_compiling, unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); 
 	subTask(message);
 }
 
@@ -94,7 +94,7 @@
  * Notification while within a compile that a unit has finished being compiled.
  */
 public void compiled(SourceFile unit) {
-	String message = Util.bind("build.compiling", unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); //$NON-NLS-1$
+	String message = Messages.bind(Messages.build_compiling, unit.resource.getFullPath().removeLastSegments(1).makeRelative().toString()); 
 	subTask(message);
 	updateProgressDelta(progressPerCompilationUnit);
 	checkCancelWithinCompiler();
@@ -107,7 +107,7 @@
 	FixedWarningCount = this.fixedWarningCount;
 
 	updateProgress(1.0f);
-	subTask(Util.bind("build.done")); //$NON-NLS-1$
+	subTask(Messages.build_done); 
 	if (monitor != null)
 		monitor.done();
 	this.previousSubtask = null;
@@ -126,28 +126,28 @@
 	buffer.append('(');
 	if (numNew > 0) {
 		// (Found x errors + y warnings)
-		buffer.append(Util.bind("build.foundHeader")); //$NON-NLS-1$
+		buffer.append(Messages.build_foundHeader); 
 		buffer.append(' ');
 		if (displayBoth || newErrorCount > 0) {
 			if (newErrorCount == 1)
-				buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
+				buffer.append(Messages.build_oneError); 
 			else
-				buffer.append(Util.bind("build.multipleErrors", String.valueOf(newErrorCount))); //$NON-NLS-1$
+				buffer.append(Messages.bind(Messages.build_multipleErrors, String.valueOf(newErrorCount))); 
 			if (displayBoth || newWarningCount > 0)
 				buffer.append(" + "); //$NON-NLS-1$
 		}
 		if (displayBoth || newWarningCount > 0) {
 			if (newWarningCount == 1)
-				buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
+				buffer.append(Messages.build_oneWarning); 
 			else
-				buffer.append(Util.bind("build.multipleWarnings", String.valueOf(newWarningCount))); //$NON-NLS-1$
+				buffer.append(Messages.bind(Messages.build_multipleWarnings, String.valueOf(newWarningCount))); 
 		}
 		if (numFixed > 0)
 			buffer.append(", "); //$NON-NLS-1$
 	}
 	if (numFixed > 0) {
 		// (Fixed x errors + y warnings) or (Found x errors + y warnings, Fixed x + y)
-		buffer.append(Util.bind("build.fixedHeader")); //$NON-NLS-1$
+		buffer.append(Messages.build_fixedHeader); 
 		buffer.append(' ');
 		if (displayBoth) {
 			buffer.append(String.valueOf(fixedErrorCount));
@@ -156,17 +156,17 @@
 		} else {
 			if (fixedErrorCount > 0) {
 				if (fixedErrorCount == 1)
-					buffer.append(Util.bind("build.oneError")); //$NON-NLS-1$
+					buffer.append(Messages.build_oneError); 
 				else
-					buffer.append(Util.bind("build.multipleErrors", String.valueOf(fixedErrorCount))); //$NON-NLS-1$
+					buffer.append(Messages.bind(Messages.build_multipleErrors, String.valueOf(fixedErrorCount))); 
 				if (fixedWarningCount > 0)
 					buffer.append(" + "); //$NON-NLS-1$
 			}
 			if (fixedWarningCount > 0) {
 				if (fixedWarningCount == 1)
-					buffer.append(Util.bind("build.oneWarning")); //$NON-NLS-1$
+					buffer.append(Messages.build_oneWarning); 
 				else
-					buffer.append(Util.bind("build.multipleWarnings", String.valueOf(fixedWarningCount))); //$NON-NLS-1$
+					buffer.append(Messages.bind(Messages.build_multipleWarnings, String.valueOf(fixedWarningCount))); 
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
index c336942..56ce053 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,7 +14,7 @@
 import org.eclipse.core.runtime.*;
 
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 
@@ -25,15 +25,15 @@
 String binaryLocation;
 SimpleLookupTable directoryCache;
 String[] missingPackageHolder = new String[1];
-AccessRestriction accessRestriction;
+AccessRuleSet accessRuleSet;
 
-ClasspathDirectory(IContainer binaryFolder, boolean isOutputFolder, AccessRestriction accessRule) {
+ClasspathDirectory(IContainer binaryFolder, boolean isOutputFolder, AccessRuleSet accessRuleSet) {
 	this.binaryFolder = binaryFolder;
 	this.isOutputFolder = isOutputFolder;
 	IPath location = binaryFolder.getLocation();
 	this.binaryLocation = location != null ? location.addTrailingSeparator().toString() : ""; //$NON-NLS-1$
 	this.directoryCache = new SimpleLookupTable(5);
-	this.accessRestriction = accessRule;
+	this.accessRuleSet = accessRuleSet;
 }
 
 public void cleanup() {
@@ -84,8 +84,8 @@
 	if (!(o instanceof ClasspathDirectory)) return false;
 
 	ClasspathDirectory dir = (ClasspathDirectory) o;
-	if (this.accessRestriction != dir.accessRestriction)
-		if (this.accessRestriction == null || !this.accessRestriction.equals(dir.accessRestriction))
+	if (this.accessRuleSet != dir.accessRuleSet)
+		if (this.accessRuleSet == null || !this.accessRuleSet.equals(dir.accessRuleSet))
 			return false;
 	return this.binaryFolder.equals(dir.binaryFolder);
 } 
@@ -96,9 +96,9 @@
 	try {
 		ClassFileReader reader = ClassFileReader.read(binaryLocation + qualifiedBinaryFileName);
 		if (reader != null) {
-			if (this.accessRestriction == null)
+			if (this.accessRuleSet == null)
 				return new NameEnvironmentAnswer(reader, null);
-			return new NameEnvironmentAnswer(reader, this.accessRestriction.getViolatedRestriction(qualifiedBinaryFileName.toCharArray(), null));
+			return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(qualifiedBinaryFileName.toCharArray()));
 		}
 	} catch (Exception e) {
 		// handle the case when the project is the output folder and the top-level package is a linked folder
@@ -110,9 +110,9 @@
 					try {
 						ClassFileReader reader = ClassFileReader.read(location.toString());
 						if (reader != null) {
-							if (this.accessRestriction == null)
+							if (this.accessRuleSet == null)
 								return new NameEnvironmentAnswer(reader, null);
-							return new NameEnvironmentAnswer(reader, this.accessRestriction.getViolatedRestriction(qualifiedBinaryFileName.toCharArray(), null));
+							return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(qualifiedBinaryFileName.toCharArray()));
 						}
 					} catch (Exception ignored) { // treat as if class file is missing
 					}
@@ -144,6 +144,9 @@
 }
 
 public String toString() {
-	return "Binary classpath directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$
+	String start = "Binary classpath directory " + this.binaryFolder.getFullPath().toString(); //$NON-NLS-1$
+	if (this.accessRuleSet == null)
+		return start;
+	return start + " with " + this.accessRuleSet; //$NON-NLS-1$
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
index df76efe..ba3817b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Tal Lev-Ami - added package cache for zip files
@@ -15,7 +15,7 @@
 import org.eclipse.core.runtime.*;
 
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.core.util.SimpleSet;
@@ -81,30 +81,30 @@
 ZipFile zipFile;
 boolean closeZipFileAtEnd;
 SimpleSet knownPackageNames;
-AccessRestriction accessRestriction;
+AccessRuleSet accessRuleSet;
 
-ClasspathJar(String zipFilename, AccessRestriction accessRestriction) {
+ClasspathJar(String zipFilename, AccessRuleSet accessRuleSet) {
 	this.zipFilename = zipFilename;
 	this.zipFile = null;
 	this.knownPackageNames = null;
-	this.accessRestriction = accessRestriction;
+	this.accessRuleSet = accessRuleSet;
 }
 
-ClasspathJar(IFile resource, AccessRestriction accessRestriction) {
+ClasspathJar(IFile resource, AccessRuleSet accessRuleSet) {
 	this.resource = resource;
 	IPath location = resource.getLocation();
 	this.zipFilename = location != null ? location.toString() : ""; //$NON-NLS-1$
 	this.zipFile = null;
 	this.knownPackageNames = null;
-	this.accessRestriction = accessRestriction;
+	this.accessRuleSet = accessRuleSet;
 }
 
-public ClasspathJar(ZipFile zipFile, AccessRestriction accessRestriction) {
+public ClasspathJar(ZipFile zipFile, AccessRuleSet accessRuleSet) {
 	this.zipFilename = zipFile.getName();
 	this.zipFile = zipFile;
 	this.closeZipFileAtEnd = false;
 	this.knownPackageNames = null;
-	this.accessRestriction = accessRestriction;
+	this.accessRuleSet = accessRuleSet;
 }
 
 public void cleanup() {
@@ -123,8 +123,8 @@
 	if (!(o instanceof ClasspathJar)) return false;
 
 	ClasspathJar jar = (ClasspathJar) o;
-	if (this.accessRestriction != jar.accessRestriction)
-		if (this.accessRestriction == null || !this.accessRestriction.equals(jar.accessRestriction))
+	if (this.accessRuleSet != jar.accessRuleSet)
+		if (this.accessRuleSet == null || !this.accessRuleSet.equals(jar.accessRuleSet))
 			return false;
 	return this.zipFilename.equals(((ClasspathJar) o).zipFilename);
 } 
@@ -135,9 +135,9 @@
 	try {
 		ClassFileReader reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
 		if (reader != null) {
-			if (this.accessRestriction == null)
+			if (this.accessRuleSet == null)
 				return new NameEnvironmentAnswer(reader, null);
-			return new NameEnvironmentAnswer(reader, this.accessRestriction.getViolatedRestriction(qualifiedBinaryFileName.toCharArray(), null));
+			return new NameEnvironmentAnswer(reader, this.accessRuleSet.getViolatedRestriction(qualifiedBinaryFileName.toCharArray()));
 		}
 	} catch (Exception e) { // treat as if class file is missing
 	}
@@ -169,6 +169,9 @@
 }
 
 public String toString() {
-	return "Classpath jar file " + zipFilename; //$NON-NLS-1$
+	String start = "Classpath jar file " + this.zipFilename; //$NON-NLS-1$
+	if (this.accessRuleSet == null)
+		return start;
+	return start + " with " + this.accessRuleSet; //$NON-NLS-1$
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
index 4531bf6..6db53e7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,7 +13,7 @@
 import org.eclipse.core.resources.*;
 import org.eclipse.core.runtime.*;
 
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 
 public abstract class ClasspathLocation {
@@ -22,16 +22,16 @@
 	return new ClasspathMultiDirectory(sourceFolder, outputFolder, inclusionPatterns, exclusionPatterns);
 }
 
-public static ClasspathLocation forBinaryFolder(IContainer binaryFolder, boolean isOutputFolder, AccessRestriction accessRestriction) {
-	return new ClasspathDirectory(binaryFolder, isOutputFolder, accessRestriction);
+public static ClasspathLocation forBinaryFolder(IContainer binaryFolder, boolean isOutputFolder, AccessRuleSet accessRuleSet) {
+	return new ClasspathDirectory(binaryFolder, isOutputFolder, accessRuleSet);
 }
 
-static ClasspathLocation forLibrary(String libraryPathname, AccessRestriction accessRestriction) {
+static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRestriction) {
 	return new ClasspathJar(libraryPathname, accessRestriction);
 }
 
-static ClasspathLocation forLibrary(IFile library, AccessRestriction accessRestriction) {
-	return new ClasspathJar(library, accessRestriction);
+static ClasspathLocation forLibrary(IFile library, AccessRuleSet accessRuleSet) {
+	return new ClasspathJar(library, accessRuleSet);
 }
 
 public abstract NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String qualifiedBinaryFileName);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
index d0f262a..90b30a2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathMultiDirectory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -56,6 +56,6 @@
 
 public String toString() {
 	return "Source classpath directory " + sourceFolder.getFullPath().toString() + //$NON-NLS-1$
-		" with binary directory " + binaryFolder.getFullPath().toString(); //$NON-NLS-1$
+		" with " + super.toString(); //$NON-NLS-1$
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java
index bc0c0c3..959f439 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ImageBuilderInternalException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
index e302427..653bb23 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,6 +20,7 @@
 import org.eclipse.jdt.internal.compiler.problem.*;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 import java.io.*;
@@ -70,7 +71,7 @@
 	try {
 		resetCollections();
 
-		notifier.subTask(Util.bind("build.analyzingDeltas")); //$NON-NLS-1$
+		notifier.subTask(Messages.build_analyzingDeltas); 
 		IResourceDelta sourceDelta = (IResourceDelta) deltas.get(javaBuilder.currentProject);
 		if (sourceDelta != null)
 			if (!findSourceFiles(sourceDelta)) return false;
@@ -89,7 +90,7 @@
 		}
 		notifier.updateProgressDelta(0.10f);
 
-		notifier.subTask(Util.bind("build.analyzingSources")); //$NON-NLS-1$
+		notifier.subTask(Messages.build_analyzingSources); 
 		addAffectedSourceFiles();
 		notifier.updateProgressDelta(0.05f);
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
index fb3cf84..96c32e8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,6 +17,7 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.core.*;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 import java.io.*;
@@ -166,27 +167,27 @@
 	} catch (CoreException e) {
 		Util.log(e, "JavaBuilder handling CoreException while building: " + currentProject.getName()); //$NON-NLS-1$
 		IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-		marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.getLocalizedMessage())); //$NON-NLS-1$
+		marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_inconsistentProject, e.getLocalizedMessage())); 
 		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 	} catch (ImageBuilderInternalException e) {
 		Util.log(e.getThrowable(), "JavaBuilder handling ImageBuilderInternalException while building: " + currentProject.getName()); //$NON-NLS-1$
 		IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-		marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.getLocalizedMessage())); //$NON-NLS-1$
+		marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_inconsistentProject, e.getLocalizedMessage())); 
 		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 	} catch (MissingClassFileException e) {
 		// do not log this exception since its thrown to handle aborted compiles because of missing class files
 		if (DEBUG)
-			System.out.println(Util.bind("build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$
+			System.out.println(Messages.bind(Messages.build_incompleteClassPath, (new String[] {e.missingClassFile}))); 
 		IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-		marker.setAttribute(IMarker.MESSAGE, Util.bind("build.incompleteClassPath", e.missingClassFile)); //$NON-NLS-1$
+		marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_incompleteClassPath, e.missingClassFile)); 
 		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 	} catch (MissingSourceFileException e) {
 		// do not log this exception since its thrown to handle aborted compiles because of missing source files
 		if (DEBUG)
-			System.out.println(Util.bind("build.missingSourceFile", e.missingSourceFile)); //$NON-NLS-1$
+			System.out.println(Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile)); 
 		removeProblemsAndTasksFor(currentProject); // make this the only problem for this project
 		IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-		marker.setAttribute(IMarker.MESSAGE, Util.bind("build.missingSourceFile", e.missingSourceFile)); //$NON-NLS-1$
+		marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_missingSourceFile, e.missingSourceFile)); 
 		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 	} finally {
 		if (!ok)
@@ -204,7 +205,7 @@
 
 private void buildAll() {
 	notifier.checkCancel();
-	notifier.subTask(Util.bind("build.preparingBuild")); //$NON-NLS-1$
+	notifier.subTask(Messages.build_preparingBuild); 
 	if (DEBUG && lastState != null)
 		System.out.println("Clearing last state : " + lastState); //$NON-NLS-1$
 	clearLastState();
@@ -215,7 +216,7 @@
 
 private void buildDeltas(SimpleLookupTable deltas) {
 	notifier.checkCancel();
-	notifier.subTask(Util.bind("build.preparingBuild")); //$NON-NLS-1$
+	notifier.subTask(Messages.build_preparingBuild); 
 	if (DEBUG && lastState != null)
 		System.out.println("Clearing last state : " + lastState); //$NON-NLS-1$
 	clearLastState(); // clear the previously built state so if the build fails, a full build will occur next time
@@ -247,7 +248,7 @@
 	} catch (CoreException e) {
 		Util.log(e, "JavaBuilder handling CoreException while cleaning: " + currentProject.getName()); //$NON-NLS-1$
 		IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-		marker.setAttribute(IMarker.MESSAGE, Util.bind("build.inconsistentProject", e.getLocalizedMessage())); //$NON-NLS-1$
+		marker.setAttribute(IMarker.MESSAGE, Messages.bind(Messages.build_inconsistentProject, e.getLocalizedMessage())); 
 		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 	} finally {
 		notifier.done();
@@ -293,7 +294,7 @@
 }
 
 private SimpleLookupTable findDeltas() {
-	notifier.subTask(Util.bind("build.readingDelta", currentProject.getName())); //$NON-NLS-1$
+	notifier.subTask(Messages.bind(Messages.build_readingDelta, currentProject.getName())); 
 	IResourceDelta delta = getDelta(currentProject);
 	SimpleLookupTable deltas = new SimpleLookupTable(3);
 	if (delta != null) {
@@ -329,7 +330,7 @@
 				if (canSkip) continue nextProject; // project has no structural changes in its output folders
 			}
 
-			notifier.subTask(Util.bind("build.readingDelta", p.getName())); //$NON-NLS-1$
+			notifier.subTask(Messages.bind(Messages.build_readingDelta, p.getName())); 
 			delta = getDelta(p);
 			if (delta != null) {
 				if (delta.getKind() != IResourceDelta.NO_CHANGE) {
@@ -440,8 +441,14 @@
 		return true;
 	}
 	if (n < newLength || o < oldLength) {
-		if (DEBUG)
-			System.out.println("Number of binary folders/jar files has changed"); //$NON-NLS-1$
+		if (DEBUG) {
+			System.out.println("Number of binary folders/jar files has changed:"); //$NON-NLS-1$
+			for (int i = 0; i < newLength; i++)
+				System.out.println(newBinaryLocations[i]);
+			System.out.println("was:"); //$NON-NLS-1$
+			for (int i = 0; i < oldLength; i++)
+				System.out.println(oldBinaryLocations[i]);
+		}
 		return true;
 	}
 	return false;
@@ -504,7 +511,7 @@
 			char[] f = filters[i];
 			if (f.length == 0) continue;
 			if (f[f.length - 1] == '/')
-				extraResourceFolderFilters[--folderCount] = new String(CharOperation.subarray(f, 0, f.length - 1));
+				extraResourceFolderFilters[--folderCount] = new String(f, 0, f.length - 1);
 			else
 				extraResourceFileFilters[--fileCount] = f;
 		}
@@ -535,7 +542,7 @@
 		removeProblemsAndTasksFor(currentProject); // remove all compilation problems
 
 		IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
-		marker.setAttribute(IMarker.MESSAGE, Util.bind("build.abortDueToClasspathProblems")); //$NON-NLS-1$
+		marker.setAttribute(IMarker.MESSAGE, Messages.build_abortDueToClasspathProblems); 
 		marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 		return false;
 	}
@@ -558,8 +565,8 @@
 			IMarker marker = currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER);
 			marker.setAttribute(IMarker.MESSAGE,
 				isClasspathBroken(prereq.getRawClasspath(), p)
-					? Util.bind("build.prereqProjectHasClasspathProblems", p.getName()) //$NON-NLS-1$
-					: Util.bind("build.prereqProjectMustBeRebuilt", p.getName())); //$NON-NLS-1$
+					? Messages.bind(Messages.build_prereqProjectHasClasspathProblems, p.getName()) 
+					: Messages.bind(Messages.build_prereqProjectMustBeRebuilt, p.getName())); 
 			marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
 			return false;
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java
index aed06aa..481bc45 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingClassFileException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java
index fd29527..f19b704 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/MissingSourceFileException.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
index f8275fa..3fe31fc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -140,7 +140,7 @@
 								ClasspathLocation.forBinaryFolder(
 										binaryFolder, 
 										true, 
-										entry.getImportRestriction());
+										entry.getAccessRuleSet());
 							bLocations.add(bLocation);
 							if (binaryLocationsPerProject != null) { // normal builder mode
 								ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(prereqProject);
@@ -165,15 +165,19 @@
 					if (resource instanceof IFile) {
 						if (!(org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(path.lastSegment())))
 							continue nextEntry;
-						AccessRestriction restriction = JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
-																			? null
-																			: entry.getImportRestriction();
-						bLocation = ClasspathLocation.forLibrary((IFile) resource, restriction);
+						AccessRuleSet accessRuleSet = 
+							(JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
+								? null
+								: entry.getAccessRuleSet();
+						bLocation = ClasspathLocation.forLibrary((IFile) resource, accessRuleSet);
 					} else if (resource instanceof IContainer) {
-						AccessRestriction restriction = JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
-																			? null
-																			: entry.getImportRestriction();
-						bLocation = ClasspathLocation.forBinaryFolder((IContainer) target, false, restriction);	 // is library folder not output folder
+						AccessRuleSet accessRuleSet = 
+							(JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
+								? null
+								: entry.getAccessRuleSet();
+						bLocation = ClasspathLocation.forBinaryFolder((IContainer) target, false, accessRuleSet);	 // is library folder not output folder
 					}
 					bLocations.add(bLocation);
 					if (binaryLocationsPerProject != null) { // normal builder mode
@@ -191,10 +195,12 @@
 				} else if (target instanceof File) {
 					if (!(org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(path.lastSegment())))
 						continue nextEntry;
-					AccessRestriction restriction = JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
-																		? null
-																		: entry.getImportRestriction();
-					bLocations.add(ClasspathLocation.forLibrary(path.toString(), restriction));
+					AccessRuleSet accessRuleSet = 
+						(JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true))
+							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
+								? null
+								: entry.getAccessRuleSet();
+					bLocations.add(ClasspathLocation.forLibrary(path.toString(), accessRuleSet));
 				}
 				continue nextEntry;
 		}
@@ -253,6 +259,7 @@
 
 private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName) {
 	if (initialTypeNames != null) {
+		// TODO (kent) should use a hash set to avoid linear search once massive source set is being processed
 		for (int i = 0, l = initialTypeNames.length; i < l; i++) {
 			if (qualifiedTypeName.equals(initialTypeNames[i])) {
 				if (isIncrementalBuild)
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java
index 144d38a..590df26 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java
index 7d47e62..6f81509 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ProblemFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java
index 91036b2..4ba3cf3 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/QualifiedNameSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java
index 9c8a57b..3521aec 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ReferenceCollection.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java
index 85f2ae2..61c27f8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/SourceFile.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -100,7 +100,9 @@
 	int lastIndex = CharOperation.lastIndexOf('/', typeName);
 	return CharOperation.splitOn('/', typeName, 0, lastIndex);
 }
-
+public int hashCode() {
+	return this.initialTypeName.hashCode();
+}
 String typeLocator() {
 	return this.resource.getProjectRelativePath().toString();
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
index fb01d61..fccb5fe 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,8 +14,10 @@
 import org.eclipse.core.runtime.*;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.AccessRule;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+import org.eclipse.jdt.internal.core.ClasspathAccessRule;
 
 import java.io.*;
 import java.util.*;
@@ -41,7 +43,7 @@
 private StringSet structurallyChangedTypes;
 public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed
 
-static final byte VERSION = 0x0009; // added AccessRestrictions
+static final byte VERSION = 0x0011; // added discouraged access rules
 
 static final byte SOURCE_FOLDER = 1;
 static final byte BINARY_FOLDER = 2;
@@ -303,25 +305,35 @@
 	return newState;
 }
 
+private static char[] readName(DataInputStream in) throws IOException {
+	int nLength = in.readInt();
+	char[] name = new char[nLength];
+	for (int j = 0; j < nLength; j++)
+		name[j] = in.readChar();
+	return name;
+}
+
 private static char[][] readNames(DataInputStream in) throws IOException {
 	int length = in.readInt();
 	char[][] names = new char[length][];
-	for (int i = 0; i < length; i++) {
-		int nLength = in.readInt();
-		char[] name = new char[nLength];
-		for (int j = 0; j < nLength; j++)
-			name[j] = in.readChar();
-		names[i] = name;
-	}
+	for (int i = 0; i < length; i++) 
+		names[i] = readName(in);
 	return names;
 }
 
-private static AccessRestriction readRestriction(DataInputStream in) throws IOException {
-	if (in.readBoolean())
-		// skip the AccessRestriction.furtherRestriction until we decide if it will be used
-		return new AccessRestriction(in.readUTF(), readNames(in), readNames(in), null);
-
-	return null; // no restriction specified
+private static AccessRuleSet readRestriction(DataInputStream in) throws IOException {
+	int length = in.readInt();
+	if (length == 0) return null; // no restriction specified
+	AccessRule[] accessRules = new AccessRule[length];
+	for (int i = 0; i < length; i++) {
+		char[] pattern = readName(in);
+		int problemId = in.readInt();
+		accessRules[i] = new ClasspathAccessRule(pattern, problemId);
+	}
+	String messageTemplate = in.readUTF();
+	AccessRuleSet accessRuleSet = new AccessRuleSet(accessRules);
+	accessRuleSet.messageTemplate = messageTemplate;
+	return accessRuleSet;
 }
 
 void tagAsNoopBuild() {
@@ -408,7 +420,7 @@
 			ClasspathDirectory cd = (ClasspathDirectory) c;
 			out.writeUTF(cd.binaryFolder.getFullPath().toString());
 			out.writeBoolean(cd.isOutputFolder);
-			writeRestriction(cd.accessRestriction, out);
+			writeRestriction(cd.accessRuleSet, out);
 		} else {
 			ClasspathJar jar = (ClasspathJar) c;
 			if (jar.resource == null) {
@@ -418,7 +430,7 @@
 				out.writeByte(INTERNAL_JAR);
 				out.writeUTF(jar.resource.getFullPath().toString());
 			}
-			writeRestriction(jar.accessRestriction, out);
+			writeRestriction(jar.accessRuleSet, out);
 		}
 	}
 
@@ -561,27 +573,35 @@
 	}
 }
 
+private void writeName(char[] name, DataOutputStream out) throws IOException {
+	int nLength = name.length;
+	out.writeInt(nLength);
+	for (int j = 0; j < nLength; j++)
+		out.writeChar(name[j]);
+}
+
 private void writeNames(char[][] names, DataOutputStream out) throws IOException {
 	int length = names == null ? 0 : names.length;
 	out.writeInt(length);
-	for (int i = 0; i < length; i++) {
-		char[] name = names[i];
-		int nLength = name.length;
-		out.writeInt(nLength);
-		for (int j = 0; j < nLength; j++)
-			out.writeChar(name[j]);
-	}
+	for (int i = 0; i < length; i++)
+		writeName(names[i], out);
 }
 
-private void writeRestriction(AccessRestriction restriction, DataOutputStream out) throws IOException {
-	if (restriction == null) {
-		out.writeBoolean(false);
+private void writeRestriction(AccessRuleSet accessRuleSet, DataOutputStream out) throws IOException {
+	if (accessRuleSet == null) {
+		out.writeInt(0);
 	} else {
-		out.writeBoolean(true);
-		out.writeUTF(restriction.getMessageTemplate());
-		writeNames(restriction.getExclusionPatterns(), out);
-		writeNames(restriction.getInclusionPatterns(), out);
-		// skip the AccessRestriction.furtherRestriction until we decide if it will be used
+		AccessRule[] accessRules = accessRuleSet.getAccessRules();
+		int length = accessRules.length;
+		out.writeInt(length);
+		if (length != 0) { 
+			for (int i = 0; i < length; i++) {
+				AccessRule accessRule = accessRules[i];
+				writeName(accessRule.pattern, out);
+				out.writeInt(accessRule.problemId);
+			}
+			out.writeUTF(accessRuleSet.messageTemplate);
+		}
 	}
 }
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java
index a22ca99..a5e0b70 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/StringSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java
index c109954..03427d9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/WorkQueue.java
@@ -1,25 +1,25 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.builder;
 
-import java.util.*;
+import org.eclipse.jdt.internal.core.util.SimpleSet;
 
 public class WorkQueue {
 
-ArrayList needsCompileList;
-ArrayList compiledList;
+private SimpleSet needsCompileList;
+private SimpleSet compiledList;
 
 public WorkQueue() {
-	this.needsCompileList = new ArrayList(11);
-	this.compiledList = new ArrayList(11);
+	this.needsCompileList = new SimpleSet();
+	this.compiledList = new SimpleSet();
 }
 
 public void add(SourceFile element) {
@@ -42,11 +42,11 @@
 }
 
 public boolean isCompiled(SourceFile element) {
-	return compiledList.contains(element);
+	return compiledList.includes(element);
 }
 
 public boolean isWaiting(SourceFile element) {
-	return needsCompileList.contains(element);
+	return needsCompileList.includes(element);
 }
 
 public String toString() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
index cc0cc1b..f0656bf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java
index 8a39a8b..39c5bff 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/GlobalVariableWrapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java
index fc8bab9..bcdee8d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/eval/RequestorWrapper.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
index 3e80c7d..1516c51 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/ChangeCollector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
index bd821c6..cc6b329 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java
index 23ab832..90bf5d0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,12 +16,12 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jdt.core.IClassFile;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.BasicCompilationUnit;
@@ -36,7 +36,7 @@
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
 import org.eclipse.jdt.internal.core.util.Util;
 
-public abstract class HierarchyBuilder implements IHierarchyRequestor {
+public abstract class HierarchyBuilder {
 	/**
 	 * The hierarchy being built.
 	 */
@@ -124,81 +124,49 @@
 		}
 	}
 	/**
-	 * @see IHierarchyRequestor
+	 * Connect the supplied type to its superclass & superinterfaces.
+	 * The superclass & superinterfaces are the identical binary or source types as
+	 * supplied by the name environment.
 	 */
 	public void connect(
-		IGenericType suppliedType,
-		IGenericType superclass,
-		IGenericType[] superinterfaces) {
+		IGenericType type,
+		IType typeHandle,
+		IType superclassHandle,
+		IType[] superinterfaceHandles) {
 
-		// convert all infos to handles
-		IType typeHandle = getHandle(suppliedType);
 		/*
 		 * Temporary workaround for 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class
 		 */
 		if (typeHandle == null)
 			return;
-		IType superHandle = null;
-		if (superclass != null) {
-			if (superclass instanceof HierarchyResolver.MissingType) {
-				this.hierarchy.missingTypes.add(((HierarchyResolver.MissingType)superclass).simpleName);
-			} else {
-				superHandle = getHandle(superclass);
-			}
-		}
-		IType[] interfaceHandles = null;
-		if (superinterfaces != null && superinterfaces.length > 0) {
-			int length = superinterfaces.length;
-			IType[] resolvedInterfaceHandles = new IType[length];
-			int index = 0;
-			for (int i = 0; i < length; i++) {
-				IGenericType superInterface = superinterfaces[i];
-				if (superInterface != null) {
-					if (superInterface instanceof HierarchyResolver.MissingType) {
-						this.hierarchy.missingTypes.add(((HierarchyResolver.MissingType)superInterface).simpleName);
-					} else {
-						resolvedInterfaceHandles[index] = getHandle(superInterface);
-						if (resolvedInterfaceHandles[index] != null) {
-							index++;
-						}
-					}
-				}
-			}
-			// resize
-			System.arraycopy(
-				resolvedInterfaceHandles,
-				0,
-				interfaceHandles = new IType[index],
-				0,
-				index);
-		}
 		if (TypeHierarchy.DEBUG) {
 			System.out.println(
 				"Connecting: " + ((JavaElement) typeHandle).toStringWithAncestors()); //$NON-NLS-1$
 			System.out.println(
 				"  to superclass: " //$NON-NLS-1$
-					+ (superHandle == null
+					+ (superclassHandle == null
 						? "<None>" //$NON-NLS-1$
-						: ((JavaElement) superHandle).toStringWithAncestors()));
+						: ((JavaElement) superclassHandle).toStringWithAncestors()));
 			System.out.print("  and superinterfaces:"); //$NON-NLS-1$
-			if (interfaceHandles == null || interfaceHandles.length == 0) {
+			if (superinterfaceHandles == null || superinterfaceHandles.length == 0) {
 				System.out.println(" <None>"); //$NON-NLS-1$
 			} else {
 				System.out.println();
-				for (int i = 0, length = interfaceHandles.length; i < length; i++) {
+				for (int i = 0, length = superinterfaceHandles.length; i < length; i++) {
+					if (superinterfaceHandles[i] == null) continue;
 					System.out.println(
-						"    " + ((JavaElement) interfaceHandles[i]).toStringWithAncestors()); //$NON-NLS-1$
+						"    " + ((JavaElement) superinterfaceHandles[i]).toStringWithAncestors()); //$NON-NLS-1$
 				}
 			}
 		}
 		// now do the caching
-		switch (suppliedType.getKind()) {
+		switch (type.getKind()) {
 			case IGenericType.CLASS_DECL :
 			case IGenericType.ENUM_DECL :
-				if (superHandle == null) {
+				if (superclassHandle == null) {
 					this.hierarchy.addRootClass(typeHandle);
 				} else {
-					this.hierarchy.cacheSuperclass(typeHandle, superHandle);
+					this.hierarchy.cacheSuperclass(typeHandle, superclassHandle);
 				}
 				break;
 			case IGenericType.INTERFACE_DECL :
@@ -206,29 +174,30 @@
 				this.hierarchy.addInterface(typeHandle);
 				break;
 		}		
-		if (interfaceHandles == null) {
-			interfaceHandles = TypeHierarchy.NO_TYPE;
+		if (superinterfaceHandles == null) {
+			superinterfaceHandles = TypeHierarchy.NO_TYPE;
 		}
-		this.hierarchy.cacheSuperInterfaces(typeHandle, interfaceHandles);
+		this.hierarchy.cacheSuperInterfaces(typeHandle, superinterfaceHandles);
 		 
 		// record flags
-		this.hierarchy.cacheFlags(typeHandle, suppliedType.getModifiers());
+		this.hierarchy.cacheFlags(typeHandle, type.getModifiers());
 	}
 	/**
 	 * Returns a handle for the given generic type or null if not found.
 	 */
-	protected IType getHandle(IGenericType genericType) {
+	protected IType getHandle(IGenericType genericType, ReferenceBinding binding) {
 		if (genericType == null)
 			return null;
 		if (genericType instanceof HierarchyType) {
 			IType handle = (IType)this.infoToHandle.get(genericType);
 			if (handle == null) {
 				handle = ((HierarchyType)genericType).typeHandle;
+				handle = (IType) ((JavaElement) handle).resolved(binding);
 				this.infoToHandle.put(genericType, handle);
 			}
 			return handle;
 		} else if (genericType.isBinaryType()) {
-			IClassFile classFile = (IClassFile) this.infoToHandle.get(genericType);
+			ClassFile classFile = (ClassFile) this.infoToHandle.get(genericType);
 			// if it's null, it's from outside the region, so do lookup
 			if (classFile == null) {
 				IType handle = lookupBinaryHandle((IBinaryType) genericType);
@@ -236,17 +205,13 @@
 					return null;
 				// case of an anonymous type (see 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class)
 				// optimization: remember the handle for next call (case of java.io.Serializable that a lot of classes implement)
-				this.infoToHandle.put(genericType, handle.getParent());
-				return handle;
-			} else {
-				try {
-					return classFile.getType();
-				} catch (JavaModelException e) {
-					return null;
-				}
-			}
+				classFile = (ClassFile) handle.getParent();
+				this.infoToHandle.put(genericType, classFile);
+			} 
+			return new ResolvedBinaryType(classFile, classFile.getTypeName(), new String(binding.computeUniqueKey()));
 		} else if (genericType instanceof SourceTypeElementInfo) {
-			return ((SourceTypeElementInfo) genericType).getHandle();
+			IType handle = ((SourceTypeElementInfo) genericType).getHandle();
+			return (IType) ((JavaElement) handle).resolved(binding);
 		} else
 			return null;
 	}
@@ -292,12 +257,12 @@
  * Create an ICompilationUnit info from the given compilation unit on disk.
  */
 protected ICompilationUnit createCompilationUnitFromPath(Openable handle, String osPath) {
-	return 
-		new BasicCompilationUnit(
-			null,
-			null,
-			osPath,
-			handle);
+	final char[] elementName = handle.getElementName().toCharArray();
+	return new BasicCompilationUnit(null/* no source*/, null/* no package */, osPath, handle) {
+		public char[] getFileName() {
+			return elementName;
+		}
+	};
 }
 	/**
  * Creates the type info from the given class file on disk and
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
index b6efb5f..da7f0c4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -61,7 +61,7 @@
 import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.Member;
 import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
@@ -69,61 +69,18 @@
 
 public class HierarchyResolver implements ITypeRequestor {
 	
-	/*
-	 * A wrapper around the simple name of a type that is missing.
-	 */
-	public class MissingType implements IGenericType {
-		public String simpleName;
-		
-		public MissingType(String simpleName) {
-			this.simpleName = simpleName;
-		}
-	
-		/**
-		 * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
-		 */
-		public char[] getFileName() {
-			return null;
-		}
-		
-		/**
-		 * @see IGenericType#getModifiers()
-		 */
-		public int getModifiers() {
-			return 0;
-		}
-	
-		/**
-		 * @see IGenericType#isBinaryType()
-		 */
-		public boolean isBinaryType() {
-			return false;
-		}
-	
-		/**
-		 * @see org.eclipse.jdt.internal.compiler.env.IGenericType#getKind()
-		 */
-		public int getKind() {
-			return 0;
-		}
-		
-		public String toString() {
-			return "Missing type: " + this.simpleName; //$NON-NLS-1$
-		}
-	
-	}
 	private ReferenceBinding focusType;
 	private boolean superTypesOnly;
 	private boolean hasMissingSuperClass;
 	LookupEnvironment lookupEnvironment;
 	private CompilerOptions options;
-	HierarchyBuilder requestor;
+	HierarchyBuilder builder;
 	private ReferenceBinding[] typeBindings;
 
 	private int typeIndex;
 	private IGenericType[] typeModels;
 	
-public HierarchyResolver(INameEnvironment nameEnvironment, Map settings, HierarchyBuilder requestor, IProblemFactory problemFactory) {
+public HierarchyResolver(INameEnvironment nameEnvironment, Map settings, HierarchyBuilder builder, IProblemFactory problemFactory) {
 	// create a problem handler with the 'exit after all problems' handling policy
 	this.options = new CompilerOptions(settings);
 	IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems();
@@ -131,10 +88,10 @@
 
 	this.setEnvironment(
 		new LookupEnvironment(this, this.options, problemReporter, nameEnvironment),
-		requestor);
+		builder);
 }
-public HierarchyResolver(LookupEnvironment lookupEnvironment, HierarchyBuilder requestor) {
-	this.setEnvironment(lookupEnvironment, requestor);
+public HierarchyResolver(LookupEnvironment lookupEnvironment, HierarchyBuilder builder) {
+	this.setEnvironment(lookupEnvironment, builder);
 }
 
 /**
@@ -158,7 +115,7 @@
 public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) {
 	//System.out.println("Cannot accept compilation units inside the HierarchyResolver.");
 	this.lookupEnvironment.problemReporter.abortDueToInternalError(
-		new StringBuffer(Util.bind("accept.cannot")) //$NON-NLS-1$
+		new StringBuffer(Messages.accept_cannot) 
 			.append(sourceUnit.getFileName())
 			.toString());
 }
@@ -200,11 +157,11 @@
 	}
 }
 /*
- * Find the super class of the given type in the cache.
- * Returns a MissingType if the class is not found,
- * or null if type has no super class.
+ * Creates the super class handle of the given type.
+ * Returns null if the type has no super class.
+ * Adds the simple name to the hierarchy missing types if the class is not found and returns null.
  */
-private IGenericType findSuperClass(IGenericType type, ReferenceBinding typeBinding) {
+private IType findSuperClass(IGenericType type, ReferenceBinding typeBinding) {
 	ReferenceBinding superBinding = typeBinding.superclass();
 	if (superBinding != null) {
 		superBinding = (ReferenceBinding) superBinding.erasure();
@@ -229,23 +186,24 @@
 				char[] simpleName = lastSeparator == -1 ? superclassName : CharOperation.subarray(superclassName, lastSeparator+1, superclassName.length);
 				if (!CharOperation.equals(simpleName, TypeConstants.OBJECT)) {
 					this.hasMissingSuperClass = true;
-					return new MissingType(new String(simpleName));
+					this.builder.hierarchy.missingTypes.add(new String(simpleName));
+					return null;
 				}
 			}
 		}
 		for (int t = this.typeIndex; t >= 0; t--) {
 			if (this.typeBindings[t] == superBinding) {
-				return this.typeModels[t];
+				return this.builder.getHandle(this.typeModels[t], superBinding);
 			}
 		}
 	} 
 	return null;
 }
 /*
- * Find the super interfaces of the given type in the cache.
- * Returns a MissingType if the interface is not found.
+ * Returns the handles of the super interfaces of the given type.
+ * Adds the simple name to the hierarchy missing types if an interface is not found (but don't put null in the returned array)
  */
-private IGenericType[] findSuperInterfaces(IGenericType type, ReferenceBinding typeBinding) {
+private IType[] findSuperInterfaces(IGenericType type, ReferenceBinding typeBinding) {
 	char[][] superInterfaceNames;
 	char separator;
 	if (type instanceof IBinaryType) {
@@ -286,7 +244,8 @@
 	int bindingIndex = 0;
 	int bindingLength = interfaceBindings == null ? 0 : interfaceBindings.length;
 	int length = superInterfaceNames == null ? 0 : superInterfaceNames.length;
-	IGenericType[] superinterfaces = new IGenericType[length];
+	IType[] superinterfaces = new IType[length];
+	int index = 0;
 	next : for (int i = 0; i < length; i++) {
 		char[] superInterfaceName = superInterfaceNames[i];
 		int lastSeparator = CharOperation.lastIndexOf(separator, superInterfaceName);
@@ -311,14 +270,16 @@
 				bindingIndex++;
 				for (int t = this.typeIndex; t >= 0; t--) {
 					if (this.typeBindings[t] == interfaceBinding) {
-						superinterfaces[i] = this.typeModels[t];
+						superinterfaces[index++] = this.builder.getHandle(this.typeModels[t], interfaceBinding);
 						continue next;
 					}
 				}
 			}
 		}
-		superinterfaces[i] = new MissingType(new String(simpleName));
+		this.builder.hierarchy.missingTypes.add(new String(simpleName));
 	}
+	if (index != length)
+		System.arraycopy(superinterfaces, 0, superinterfaces = new IType[index], 0, index);
 	return superinterfaces;
 }
 private void remember(IGenericType suppliedType, ReferenceBinding typeBinding) {
@@ -463,19 +424,20 @@
 			continue; // ignore types outside of hierarchy
 		}
 
-		IGenericType superclass;
+		IType superclass;
 		if (typeBinding.isInterface()){ // do not connect interfaces to Object
 			superclass = null;
 		} else {
 			superclass = findSuperClass(suppliedType, typeBinding);
 		}
-		IGenericType[] superinterfaces = findSuperInterfaces(suppliedType, typeBinding);
+		IType[] superinterfaces = findSuperInterfaces(suppliedType, typeBinding);
 		
-		this.requestor.connect(suppliedType, superclass, superinterfaces);
+		this.builder.connect(suppliedType, this.builder.getHandle(suppliedType, typeBinding), superclass, superinterfaces);
 	}
 	// add java.lang.Object only if the super class is not missing
 	if (!this.hasMissingSuperClass && objectIndex > -1) {
-		this.requestor.connect(this.typeModels[objectIndex], null, null);
+		IGenericType objectType = this.typeModels[objectIndex];
+		this.builder.connect(objectType, this.builder.getHandle(objectType, this.typeBindings[objectIndex]), null, null);
 	}
 }
 private void reset(){
@@ -515,7 +477,7 @@
 				}
 			}		
 			this.superTypesOnly = true;
-			reportHierarchy(this.requestor.getType(), null, binaryTypeBinding);
+			reportHierarchy(this.builder.getType(), null, binaryTypeBinding);
 		} else {
 			org.eclipse.jdt.core.ICompilationUnit cu = ((SourceTypeElementInfo)suppliedType).getHandle().getCompilationUnit();
 			HashSet localTypes = new HashSet();
@@ -552,7 +514,7 @@
 		
 		CompilationUnitDeclaration focusUnit = null;
 		ReferenceBinding focusBinaryBinding = null;
-		IType focus = this.requestor.getType();
+		IType focus = this.builder.getType();
 		Openable focusOpenable = null;
 		if (focus != null) {
 			if (focus.isBinary()) {
@@ -610,7 +572,7 @@
 					// create parsed unit from file
 					IResource file = cu.getResource();
 					String osPath = file.getLocation().toOSString();
-					ICompilationUnit sourceUnit = this.requestor.createCompilationUnitFromPath(openable, osPath);
+					ICompilationUnit sourceUnit = this.builder.createCompilationUnitFromPath(openable, osPath);
 					
 					CompilationResult unitResult = new CompilationResult(sourceUnit, i, openablesLength, this.options.maxProblemsPerUnit); 
 					parsedUnit = parser.dietParse(sourceUnit, unitResult);
@@ -644,11 +606,11 @@
 				} else {
 					// create binary type from file
 					if (classFile.getPackageFragmentRoot().isArchive()) {
-						binaryType = this.requestor.createInfoFromClassFileInJar(classFile);
+						binaryType = this.builder.createInfoFromClassFileInJar(classFile);
 					} else {
 						IResource file = classFile.getResource();
 						String osPath = file.getLocation().toOSString();
-						binaryType = this.requestor.createInfoFromClassFile(classFile, osPath);
+						binaryType = this.builder.createInfoFromClassFile(classFile, osPath);
 					}
 				}
 				if (binaryType != null) {
@@ -730,9 +692,9 @@
 		reset();
 	}
 }
-private void setEnvironment(LookupEnvironment lookupEnvironment, HierarchyBuilder requestor) {
+private void setEnvironment(LookupEnvironment lookupEnvironment, HierarchyBuilder builder) {
 	this.lookupEnvironment = lookupEnvironment;
-	this.requestor = requestor;
+	this.builder = builder;
 
 	this.typeIndex = -1;
 	this.typeModels = new IGenericType[5];
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java
index 30760a2..1ba6b06 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IHierarchyRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IHierarchyRequestor.java
deleted file mode 100644
index ced2c2a..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IHierarchyRequestor.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.hierarchy;
-
-import org.eclipse.jdt.internal.compiler.env.IGenericType;
-
-public interface IHierarchyRequestor {
-/**
- * Connect the supplied type to its superclass & superinterfaces.
- * The superclass & superinterfaces are the identical binary or source types as
- * supplied by the name environment.
- */
-
-public void connect(IGenericType suppliedType, IGenericType superclass, IGenericType[] superinterfaces);
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
index 749cf53..53d8c8b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,7 +20,7 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.*;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
@@ -169,8 +169,11 @@
 
 		SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside);
 		this.nameLookup = searchableEnvironment.nameLookup;
+		Map options = project.getOptions(true);
+		// disable task tags to speed up parsing
+		options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
 		this.hierarchyResolver = 
-			new HierarchyResolver(searchableEnvironment, project.getOptions(true), this, new DefaultProblemFactory());
+			new HierarchyResolver(searchableEnvironment, options, this, new DefaultProblemFactory());
 		if (focusType != null) {
 			Member declaringMember = ((Member)focusType).getOuterMostLocalContext();
 			if (declaringMember == null) {
@@ -330,7 +333,7 @@
 		if (monitor != null) monitor.done();
 	}
 }
-protected ICompilationUnit createCompilationUnitFromPath(Openable handle,String osPath) {
+protected ICompilationUnit createCompilationUnitFromPath(Openable handle, String osPath) {
 	ICompilationUnit unit = super.createCompilationUnitFromPath(handle, osPath);
 	this.cuToHandle.put(unit, handle);
 	return unit;
@@ -429,7 +432,7 @@
 
 	/* use a special collector to collect paths and queue new subtype names */
 	IndexQueryRequestor searchRequestor = new IndexQueryRequestor() {
-		public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRestriction access) {
+		public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
 			SuperTypeReferencePattern record = (SuperTypeReferencePattern)indexRecord;
 			pathRequestor.acceptPath(documentPath, record.enclosingTypeName == IIndexConstants.ONE_ZERO);
 			char[] typeName = record.simpleName;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
index d198963..b0ae80a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,6 +12,7 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.SubProgressMonitor;
@@ -47,7 +48,7 @@
 				this.hierarchy.progressMonitor == null ? 
 					null : 
 					new SubProgressMonitor(this.hierarchy.progressMonitor, 30);
-			ArrayList allOpenablesInRegion = determineOpenablesInRegion(typeInRegionMonitor);
+			HashMap allOpenablesInRegion = determineOpenablesInRegion(typeInRegionMonitor);
 			this.hierarchy.initialize(allOpenablesInRegion.size());
 			IProgressMonitor buildMonitor = 
 				this.hierarchy.progressMonitor == null ? 
@@ -66,39 +67,51 @@
 /**
  * Configure this type hierarchy that is based on a region.
  */
-private void createTypeHierarchyBasedOnRegion(ArrayList allOpenablesInRegion, IProgressMonitor monitor) {
+private void createTypeHierarchyBasedOnRegion(HashMap allOpenablesInRegion, IProgressMonitor monitor) {
 	
 	int size = allOpenablesInRegion.size();
 	if (size != 0) {
 		this.infoToHandle = new HashMap(size);
 	}
-	Openable[] openables = new Openable[size];
-	allOpenablesInRegion.toArray(openables);
-
-	try {
-		// resolve
-		if (monitor != null) monitor.beginTask("", size * 2/* 1 for build binding, 1 for connect hierarchy*/); //$NON-NLS-1$
-		if (size > 0) {
-			this.hierarchyResolver.resolve(openables, null, monitor);
+	
+	Iterator javaProjects = allOpenablesInRegion.keySet().iterator();
+	while (javaProjects.hasNext()) {
+		ArrayList allOpenables = (ArrayList) allOpenablesInRegion.get(javaProjects.next());
+		Openable[] openables = new Openable[allOpenables.size()];
+		allOpenables.toArray(openables);
+	
+		try {
+			// resolve
+			if (monitor != null) monitor.beginTask("", size * 2/* 1 for build binding, 1 for connect hierarchy*/); //$NON-NLS-1$
+			if (size > 0) {
+				this.hierarchyResolver.resolve(openables, null, monitor);
+			}
+		} finally {
+			if (monitor != null) monitor.done();
 		}
-	} finally {
-		if (monitor != null) monitor.done();
 	}
 }
 	
 	/**
 	 * Returns all of the openables defined in the region of this type hierarchy.
+	 * Returns a map from IJavaProject to ArrayList of Openable
 	 */
-	private ArrayList determineOpenablesInRegion(IProgressMonitor monitor) {
+	private HashMap determineOpenablesInRegion(IProgressMonitor monitor) {
 
 		try {
-			ArrayList openables = new ArrayList();
+			HashMap allOpenables = new HashMap();
 			IJavaElement[] roots =
 				((RegionBasedTypeHierarchy) this.hierarchy).region.getElements();
 			int length = roots.length;
 			if (monitor != null) monitor.beginTask("", length); //$NON-NLS-1$
 			for (int i = 0; i <length; i++) {
 				IJavaElement root = roots[i];
+				IJavaProject javaProject = root.getJavaProject();
+				ArrayList openables = (ArrayList) allOpenables.get(javaProject);
+				if (openables == null) {
+					openables = new ArrayList();
+					allOpenables.put(javaProject, openables);
+				}
 				switch (root.getElementType()) {
 					case IJavaElement.JAVA_PROJECT :
 						injectAllOpenablesForJavaProject((IJavaProject) root, openables);
@@ -126,7 +139,7 @@
 				}
 				worked(monitor, 1);
 			}
-			return openables;
+			return allOpenables;
 		} finally {
 			if (monitor != null) monitor.done();
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
index b616d8f..f9ae011 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,18 +32,20 @@
 	 * The region of types for which to build the hierarchy
 	 */
 	protected IRegion region;
-
+	
 /**
  * Creates a TypeHierarchy on the types in the specified region,
  * considering first the given working copies,
- * using the given project for a name lookup contenxt. If a specific
+ * using the projects in the given region for a name lookup context. If a specific
  * type is also specified, the type hierarchy is pruned to only
  * contain the branch including the specified type.
  */
-public RegionBasedTypeHierarchy(IRegion region, IJavaProject project, ICompilationUnit[] workingCopies, IType type, boolean computeSubtypes) {
+public RegionBasedTypeHierarchy(IRegion region, ICompilationUnit[] workingCopies, IType type, boolean computeSubtypes) {
 	super(type, workingCopies, (IJavaSearchScope)null, computeSubtypes);
 	this.region = region;
-	this.project = project;
+	IJavaElement[] elements = region.getElements();
+	if (elements.length > 0)
+		this.project = elements[0].getJavaProject();
 }
 /*
  * @see TypeHierarchy#initializeRegions
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
index 4c5f51d..2a5f271 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -50,6 +50,7 @@
 import org.eclipse.jdt.internal.core.Openable;
 import org.eclipse.jdt.internal.core.Region;
 import org.eclipse.jdt.internal.core.TypeVector;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
@@ -1222,9 +1223,9 @@
 		this.progressMonitor = monitor;
 		if (monitor != null) {
 			if (this.focusType != null) {
-				monitor.beginTask(Util.bind("hierarchy.creatingOnType", this.focusType.getFullyQualifiedName()), 100); //$NON-NLS-1$
+				monitor.beginTask(Messages.bind(Messages.hierarchy_creatingOnType, this.focusType.getFullyQualifiedName()), 100); 
 			} else {
-				monitor.beginTask(Util.bind("hierarchy.creating"), 100); //$NON-NLS-1$
+				monitor.beginTask(Messages.hierarchy_creating, 100); 
 			}
 		}
 		long start = -1;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java
index e7530f0..3702006 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/AbstractDOMBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java
index a5b0c95..db3c55b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/CompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java
index 593a3b4..914af5c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -68,7 +68,7 @@
 	int[] nameRange = {nameStart, declarationEnd - 1};
 	
 	/* See 1FVII1P */
-	String importName = new String(CharOperation.subarray(fDocument, nameRange[0], nameRange[1] + 1));
+	String importName = new String(fDocument, nameRange[0], nameRange[1] + 1 - nameRange[0]);
 
 	fNode= new DOMImport(fDocument, sourceRange, importName, nameRange, onDemand, modifiers);
 	addChild(fNode);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java
index 3dc3ef9..e06d1bb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMCompilationUnit.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,10 +13,10 @@
 import org.eclipse.jdt.core.Flags;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 /**
  * DOMCompilation unit provides an implementation of IDOMCompilationUnit.
@@ -81,7 +81,7 @@
 	if (parent.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
 		return ((IPackageFragment)parent).getCompilationUnit(getName());
 	} else {
-		throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
@@ -127,7 +127,7 @@
 	if (child != null) {
 		int childStart = child.getStartPosition();
 		if (childStart > 1) {
-			setHeader(new String(CharOperation.subarray(fDocument, 0, childStart)));
+			setHeader(new String(fDocument, 0, childStart));
 		}
 	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
index b1ec8d3..257993c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMField.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,7 +16,7 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
 /**
  * DOMField provides an implementation of IDOMField.
@@ -237,7 +237,7 @@
 			DOMBuilder builder = new DOMBuilder();
 			IDOMField[] details= builder.createFields(source.toCharArray());
 			if (details.length == 0) {
-				throw new DOMException(Util.bind("dom.cannotDetail")); //$NON-NLS-1$
+				throw new DOMException(Messages.dom_cannotDetail); 
 			} else {
 				node= this;
 				for (int i= 0; i < details.length; i++) {
@@ -311,7 +311,7 @@
 		if (fInitializer != null) {
 			return fInitializer;
 		} else {
-			return new String(CharOperation.subarray(fDocument, fInitializerRange[0], fInitializerRange[1] + 1));
+			return new String(fDocument, fInitializerRange[0], fInitializerRange[1] + 1 - fInitializerRange[0]);
 		}
 	} else {
 		return null;
@@ -324,7 +324,7 @@
 	if (parent.getElementType() == IJavaElement.TYPE) {
 		return ((IType)parent).getField(getName());
 	} else {
-		throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
@@ -381,16 +381,16 @@
 				.append('=')
 				.append(fInitializer)
 				.append(';')
-				.append(Util.LINE_SEPARATOR);
+				.append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
 		} else {
 			buffer
 				.append(fDocument, fNameRange[1] + 1, fInitializerRange[0] - fNameRange[1] - 1)
 				.append(getInitializer())
 				.append(';')
-				.append(Util.LINE_SEPARATOR);
+				.append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
 		}
 	} else {
-		buffer.append(';').append(Util.LINE_SEPARATOR);
+		buffer.append(';').append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
 	}
 	return buffer.getContents();
 }
@@ -574,7 +574,7 @@
  */
 public void setName(String name) throws IllegalArgumentException {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullName); 
 	} else {
 		super.setName(name);
 		setTypeAltered(true);
@@ -585,7 +585,7 @@
  */
 public void setType(String typeName) throws IllegalArgumentException {
 	if (typeName == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullType")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullType); 
 	}
 	becomeDetailed();
 	expand();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
index 8250fe0..595da2e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,7 +14,7 @@
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
 
 /**
@@ -99,7 +99,7 @@
 			.append("import ") //$NON-NLS-1$
 			.append(fName)
 			.append(';')
-			.append(Util.LINE_SEPARATOR);
+			.append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
 	} else {
 		buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]);
 		//buffer.append(fDocument, fNameRange[0], fNameRange[1] - fNameRange[0] + 1);
@@ -130,7 +130,7 @@
 	if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
 		return ((ICompilationUnit)parent).getImport(getName());
 	} else {
-		throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
@@ -156,7 +156,7 @@
  */
 public void setName(String name) {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullName); 
 	}
 	becomeDetailed();
 	super.setName(name);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
index 43e02cc..1bd97cf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMInitializer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,9 +12,8 @@
 
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
 /**
  * DOMInitializer provides an implementation of IDOMInitializer.
@@ -108,7 +107,7 @@
 			.append(getBody())
 			.append(fDocument, fBodyRange[1] + 1, fSourceRange[1] - fBodyRange[1]);
 	} else {
-		buffer.append("{}").append(Util.LINE_SEPARATOR); //$NON-NLS-1$
+		buffer.append("{}").append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR); //$NON-NLS-1$
 	}
 }
 /**
@@ -137,7 +136,7 @@
 		if (fBody != null) {
 			return fBody;
 		} else {
-			return new String(CharOperation.subarray(fDocument, fBodyRange[0], fBodyRange[1] + 1));
+			return new String(fDocument, fBodyRange[0], fBodyRange[1] + 1 - fBodyRange[0]);
 		}
 	} else {
 		return null;
@@ -164,7 +163,7 @@
 		}
 		return ((IType) parent).getInitializer(count);
 	} else {
-		throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java
index 4ff50a3..f5555f2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMember.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -220,7 +220,7 @@
 		if (fComment != null) {
 			return fComment;
 		} else {
-			return new String(CharOperation.subarray(fDocument, fCommentRange[0], fCommentRange[1] + 1));
+			return new String(fDocument, fCommentRange[0], fCommentRange[1] + 1 - fCommentRange[0]);
 		}
 	} else {
 		return null;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
index 8481784..92f15c4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMMethod.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,7 +16,7 @@
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
 /**
  * DOMMethod provides an implementation of IDOMMethod.
@@ -245,7 +245,7 @@
  */
 public void addException(String name) throws IllegalArgumentException {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("dom.nullExceptionType")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_nullExceptionType); 
 	}
 	if (fExceptions == null) {
 		fExceptions= new String[1];
@@ -260,10 +260,10 @@
  */
 public void addParameter(String type, String name) throws IllegalArgumentException {
 	if (type == null) {
-		throw new IllegalArgumentException(Util.bind("dom.nullTypeParameter")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_nullTypeParameter); 
 	}
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("dom.nullNameParameter")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_nullNameParameter); 
 	}
 	if (fParameterNames == null) {
 		fParameterNames= new String[1];
@@ -374,7 +374,7 @@
 		if (fBody != null) {
 			return fBody;
 		} else {
-			return new String(CharOperation.subarray(fDocument, fBodyRange[0], fBodyRange[1] + 1));
+			return new String(fDocument, fBodyRange[0], fBodyRange[1] + 1 - fBodyRange[0]);
 		}
 	} else {
 		return null;
@@ -440,7 +440,7 @@
 		}
 		return ((IType)parent).getMethod(name, sigs);
 	} else {
-		throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
@@ -599,7 +599,7 @@
 	fBody= body;
 	setHasBody(body != null);
 	if (!hasBody()) {
-		fBody= ";"+Util.LINE_SEPARATOR; //$NON-NLS-1$
+		fBody= ";" + org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR; //$NON-NLS-1$
 	}
 }
 /**
@@ -641,7 +641,7 @@
  */
 public void setName(String name) {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullName); 
 	} else {
 		super.setName(name);
 	}
@@ -657,10 +657,10 @@
 			fParameterNames= null;
 			fParameterList= new char[] {'(',')'};
 		} else {
-			throw new IllegalArgumentException(Util.bind("dom.mismatchArgNamesAndTypes")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.dom_mismatchArgNamesAndTypes); 
 		}
 	} else if (names.length != types.length) {
-		throw new IllegalArgumentException(Util.bind("dom.mismatchArgNamesAndTypes")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_mismatchArgNamesAndTypes); 
 	} else if (names.length == 0) {
 		setParameters(null, null);
 	} else {
@@ -688,7 +688,7 @@
  */
 public void setReturnType(String name) throws IllegalArgumentException {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("dom.nullReturnType")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_nullReturnType); 
 	}
 	becomeDetailed();
 	fragment();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java
index 3af11f0..b9d4291 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMNode.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,7 +14,7 @@
 
 import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * DOMNode provides an implementation for <code>IDOMNode</code>.
@@ -341,23 +341,23 @@
 void basicAddChild(IDOMNode child) throws IllegalArgumentException, DOMException {
 	// verify child may be added
 	if (!canHaveChildren()) {
-		throw new DOMException(Util.bind("dom.unableAddChild")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_unableAddChild); 
 	}
 	if (child == null) {
-		throw new IllegalArgumentException(Util.bind("dom.addNullChild")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_addNullChild); 
 	}
 	if (!isAllowableChild(child)) {
-		throw new DOMException(Util.bind("dom.addIncompatibleChild")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addIncompatibleChild); 
 	}
 	if (child.getParent() != null) {
-		throw new DOMException(Util.bind("dom.addChildWithParent")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addChildWithParent); 
 	}
 	/* NOTE: To test if the child is an ancestor of this node, we
 	 * need only test if the root of this node is the child (the child
 	 * is already a root since we have just guarenteed it has no parent).
 	 */
 	if (child == getRoot()) {
-		throw new DOMException(Util.bind("dom.addAncestorAsChild")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addAncestorAsChild); 
 	}
 
 	DOMNode node= (DOMNode)child;
@@ -389,7 +389,7 @@
 	if (!isDetailed()) {
 		DOMNode detailed= getDetailedNode();
 		if (detailed == null) {
-			throw new DOMException(Util.bind("dom.cannotDetail")); //$NON-NLS-1$
+			throw new DOMException(Messages.dom_cannotDetail); 
 		}
 		if (detailed != this) {
 			shareContents(detailed);
@@ -665,23 +665,23 @@
 public void insertSibling(IDOMNode sibling) throws IllegalArgumentException, DOMException {
 	// verify sibling may be added
 	if (sibling == null) {
-		throw new IllegalArgumentException(Util.bind("dom.addNullSibling")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_addNullSibling); 
 	}
 	if (fParent == null) {
-		throw new DOMException(Util.bind("dom.addSiblingBeforeRoot")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addSiblingBeforeRoot); 
 	}
 	if (!fParent.isAllowableChild(sibling)) {
-		throw new DOMException(Util.bind("dom.addIncompatibleSibling")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addIncompatibleSibling); 
 	}
 	if (sibling.getParent() != null) {
-		throw new DOMException(Util.bind("dom.addSiblingWithParent")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addSiblingWithParent); 
 	}
 	/* NOTE: To test if the sibling is an ancestor of this node, we
 	 * need only test if the root of this node is the child (the sibling
 	 * is already a root since we have just guaranteed it has no parent).
 	 */
 	if (sibling == getRoot()) {
-		throw new DOMException(Util.bind("dom.addAncestorAsSibling")); //$NON-NLS-1$
+		throw new DOMException(Messages.dom_addAncestorAsSibling); 
 	}
 
 	DOMNode node= (DOMNode)sibling;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
index cffb592..a6ab806 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMPackage.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,7 +13,7 @@
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.jdom.*;
-import org.eclipse.jdt.internal.compiler.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
 
 /**
@@ -80,8 +80,8 @@
 			.append("package ") //$NON-NLS-1$
 			.append(fName)
 			.append(';')
-			.append(Util.LINE_SEPARATOR)
-			.append(Util.LINE_SEPARATOR);
+			.append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR)
+			.append(org.eclipse.jdt.internal.compiler.util.Util.LINE_SEPARATOR);
 	} else {
 		buffer
 			.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0])
@@ -112,7 +112,7 @@
 	if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
 		return ((ICompilationUnit)parent).getPackageDeclaration(getName());
 	} else {
-		throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java
index 4a398d2..f3a708d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMType.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,13 +15,12 @@
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.core.jdom.*;
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
 import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 /**
  * DOMType provides an implementation of IDOMType.
  *
@@ -257,7 +256,7 @@
  */
 public void addSuperInterface(String name) throws IllegalArgumentException {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("dom.addNullInterface")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_addNullInterface); 
 	}
 	if (fSuperInterfaces == null) {
 		fSuperInterfaces= new String[1];
@@ -411,7 +410,7 @@
 			return ((IType)parent).getType(getName());
 		// Note: creating local/anonymous type is not supported 
 		default:
-			throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+			throw new IllegalArgumentException(Messages.element_illegalParent); 
 	}
 }
 /**
@@ -441,7 +440,7 @@
 		if (fSuperclass != null) {
 			return fSuperclass;
 		} else {
-			return new String(CharOperation.subarray(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1));
+			return new String(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]);
 		}
 	} else {
 		return null;
@@ -650,7 +649,7 @@
  */
 public void setName(String name) throws IllegalArgumentException {
 	if (name == null) {
-		throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.element_nullName); 
 	}
 	super.setName(name);
 	Enumeration children= getChildren();
@@ -688,7 +687,7 @@
 public void setSuperInterfaces(String[] names) {
 	becomeDetailed();
 	if (names == null) {
-		throw new IllegalArgumentException(Util.bind("dom.nullInterfaces")); //$NON-NLS-1$
+		throw new IllegalArgumentException(Messages.dom_nullInterfaces); 
 	}
 	fragment();
 	fSuperInterfaces= names;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java
index 8569c62..f53b02c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/ILineStartFinder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java
index f258b16..e9b126e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SiblingEnumeration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java
index dea4793..6442feb 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -185,6 +185,6 @@
  * Creates a new parser.
  */
 protected SourceElementParser getParser(Map settings) {
-	return new SourceElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings));
+	return new SourceElementParser(this, new DefaultProblemFactory(), new CompilerOptions(settings), false/*don't report local declarations*/, true/*optimize string literals*/);
 }
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java
index 07cf5b7..f0d7e6f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ASTNodeFinder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java
index f90424d..3a2343d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java
index 10a4710..93e194b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java
index 4fa7b11..7358806 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -42,6 +42,10 @@
 			byte[] classFileBytes,
 			IConstantPool constantPool,
 			int offset) throws ClassFormatException {
+		this.classFileInfoIndex = -1;
+		this.constantValueIndex = -1;
+		this.enumConstantTypeNameIndex = -1;
+		this.enumConstantNameIndex = -1;
 		final int t = u1At(classFileBytes, 0, offset);
 		this.tag = t;
 		this.readOffset = 1;
@@ -142,12 +146,6 @@
 		return this.annotationValue;
 	}
 	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationValue()
-	 */
-	public IAnnotation getAttributeValue() {
-		return this.annotationValue;
-	}
-	/* (non-Javadoc)
 	 * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfo()
 	 */
 	public IConstantPoolEntry getClassInfo() {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java
index f8f5ac1..4f7e49c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnonymousFileSource.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnonymousFileSource.java
deleted file mode 100644
index a34b2df..0000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnonymousFileSource.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.net.URL;
-
-/**
- * An anonymous file source creates files in the given directory.
- */
-public class AnonymousFileSource {
-	File fDirectory;
-/**
- * Creates an anonymous file source which creates files in the given directory.
- */
-public AnonymousFileSource(File directory) {
-	if (!directory.exists()) {
-		directory.mkdirs();
-	} else if (!directory.isDirectory()) {
-		throw new IllegalArgumentException("Directory arguments should be a directory."); //$NON-NLS-1$
-	}
-	fDirectory = directory;	
-}
-/**
- * Allocates and returns a RandomAccessFile in R/W mode on a new anonymous file.
- * Guaranteed to be unallocated.
- */
-synchronized public RandomAccessFile allocateAnonymousFile() throws IOException {
-	
-	File file = getAnonymousFile();
-	return new RandomAccessFile(file, "rw"); //$NON-NLS-1$
-}
-/**
- * Returns a URL on a newly allocated file with the given initial content.
- * Guaranteed to be unallocated.
- */
-synchronized public URL allocateAnonymousURL(byte[] bytes) throws IOException {
-	try {
-		byte hasharray[] = java.security.MessageDigest.getInstance("SHA").digest(bytes); //$NON-NLS-1$
-		StringBuffer sb = new StringBuffer();
-		for (int i = 0; i < hasharray.length; i++) {
-			sb.append(Character.forDigit((hasharray[i] >> 4) & 0x0F, 16));
-			sb.append(Character.forDigit(hasharray[i] & 0x0F, 16));
-		}
-		sb.append(".jnk"); //$NON-NLS-1$
-		String fileName = sb.toString();
-		File file = fileForName(fileName);
-		if (!file.exists()) {
-			RandomAccessFile raf = new RandomAccessFile(file, "rw"); //$NON-NLS-1$
-			raf.write(bytes);
-			raf.close();
-		}
-		return convertFileToURL(file);
-	} 
-	catch (java.security.NoSuchAlgorithmException e) {
-		throw new IOException(e.getMessage());
-	}
-}
-/**
- * Returns a URL using the "file" protocol corresponding to the given File.
- */
-static public URL convertFileToURL(File file) {
-	try {
-		String path = file.getCanonicalPath().replace(java.io.File.separatorChar, '/');
-		return new URL("file", "", "/" + path); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-	}
-	catch (IOException ioe) {
-		throw new Error();
-	}
-}
-/**
- * Answer a File to use for the given simple file name.
- */
-File fileForName(String fileName) {
-	File dir;
-	if (fileName.length() >= 1) {
-		String dirName = Integer.toHexString((fileName.hashCode() % 255) & 255);
-		dir = new File(fDirectory, dirName);
-		dir.mkdirs();
-	} else {
-		dir = fDirectory;
-	}
-	return new File(dir, fileName);	
-}
-/**
- * Returns a new anonymous file, but does not allocate it.  
- * Not guaranteed to be free when used since it is unallocated.
- */
-synchronized public File getAnonymousFile() {
-	File file;
-	file = fileForName(getAnonymousFileName());
-	while (file.exists()) {
-		try {
-			Thread.sleep(1);
-		} 
-		catch (InterruptedException e) {
-			// ignore
-		}
-		file = fileForName(getAnonymousFileName());
-	}
-	return file;
-}
-/**
- * Returns a new anonymous file name.  
- * Not guaranteed to be free since its directory is unknown.
- */
-synchronized public String getAnonymousFileName() {
-	return getAnonymousFileName(System.currentTimeMillis());
-}
-/**
- * Returns a new anonymous file name based on the given long.  
- * Not guaranteed to be free since its directory is unknown.
- */
-synchronized public String getAnonymousFileName(long l) {
-	if (l < 0) l = -l;
-	StringBuffer sb = new StringBuffer();
-	sb.append(Character.forDigit((int)(l % 26 + 10), 36));
-	l /= 26;
-	while (l != 0) {
-		sb.append(Character.forDigit((int)(l % 36), 36));
-		l /= 36;
-	}
-	sb.append(".jnk"); //$NON-NLS-1$
-	return sb.toString();
-}
-}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
new file mode 100644
index 0000000..9140e31
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyParser.java
@@ -0,0 +1,735 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+public class BindingKeyParser {
+	
+	int keyStart;
+	
+	class Scanner {
+		static final int PACKAGE = 0;
+		static final int TYPE = 1;
+		static final int FIELD = 2;
+		static final int METHOD = 3;
+		static final int ARRAY = 4;
+		static final int LOCAL_VAR = 5;
+		static final int FLAGS = 6;
+		static final int WILDCARD = 7;
+		static final int CAPTURE = 8;
+		static final int END = 9;
+		
+		static final int START = -1;
+		
+		int index = 0, start;
+		char[] source;
+		int token = START;
+	
+		Scanner(char[] source) {
+			this.source = source;
+		}
+		
+		char[] getTokenSource() {
+			int length = this.index-this.start;
+			char[] result = new char[length];
+			System.arraycopy(this.source, this.start, result, 0, length);
+			return result;
+		}
+		
+		boolean isAtFieldOrMethodStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == '.';
+		}
+		
+		boolean isAtLocalVariableStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == '#';
+		}
+		
+		boolean isAtMemberTypeStart() {
+			return 
+				this.index < this.source.length
+				&& (this.source[this.index] == '$'
+					|| (this.source[this.index] == '.' && this.source[this.index-1] == '>'));
+		}
+		
+		boolean isAtParametersEnd() {
+			return 
+				this.index < this.source.length
+					&& this.source[this.index] == '>';
+		}
+		
+		boolean isAtParametersStart() {
+			char currentChar;
+			return 
+				this.index > 0
+				&& this.index < this.source.length
+				&& ((currentChar = this.source[this.index]) == '<'
+					|| currentChar == '%');
+		}
+		
+		boolean isAtRawTypeEnd() {
+			return 
+				this.index > 0
+				&& this.index < this.source.length
+				&& this.source[this.index] == '>';
+		}
+		
+		boolean isAtSecondaryTypeStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == '~';
+		}
+		
+		boolean isAtTypeParameterStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == 'T';
+		}
+	
+		boolean isAtTypeArgumentStart() {
+			return this.index < this.source.length && "LIZVCDBFJS[*+-!".indexOf(this.source[this.index]) != -1; //$NON-NLS-1$
+		}
+		
+		boolean isAtMethodTypeVariableStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == ':';
+		}
+
+		boolean isAtFlagsStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == '^';
+		}
+		
+		boolean isAtTypeTypeVariableStart() {
+			return 
+				this.index < this.source.length
+				&& this.source[this.index] == ':';
+		}
+		
+		int nextToken() {
+			int previousTokenEnd = this.index;
+			this.start = this.index;
+			int length = this.source.length;
+			while (this.index <= length) {
+				char currentChar = this.index == length ? Character.MIN_VALUE : this.source[this.index];
+				switch (currentChar) {
+					case 'B':
+					case 'C':
+					case 'D':
+					case 'F':
+					case 'I':
+					case 'J':
+					case 'N':
+					case 'S':
+					case 'V':
+					case 'Z':
+						// base type
+						if (this.index == previousTokenEnd) {
+							this.index++;
+							this.token = TYPE;
+							return this.token;
+						}
+						break;
+					case 'L':
+					case 'T':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+						}
+						break;
+					case ';':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							previousTokenEnd = this.start;
+						} else {
+							this.token = TYPE;
+							return this.token;
+						}
+						break;
+					case '^':
+						if (this.index == previousTokenEnd) {
+							this.index++;
+							this.start = this.index;
+							while (this.index < length && Character.isDigit(this.source[this.index]))
+								this.index++;
+							this.token = FLAGS;
+							return this.token;
+						} else {
+							switch (this.token) {
+								case METHOD:
+								case LOCAL_VAR:
+									this.token = LOCAL_VAR;
+									break;
+								case TYPE:
+									if (this.index > this.start && this.source[this.start-1] == '.')
+										this.token = FIELD;
+									break;
+							}							
+							return this.token;
+						}
+					case '$':
+					case '~':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+						} else {
+							this.token = TYPE;
+							return this.token;
+						}
+						break;
+					case '.':
+					case '%':
+					case ':':
+					case '>':
+						this.start = this.index+1;
+						previousTokenEnd = this.start;
+						break;
+					case '[':
+						while (this.index < length && this.source[this.index] == '[')
+							this.index++;
+						this.token = ARRAY;
+						return this.token;
+					case '<':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							previousTokenEnd = this.start;
+						} else if (this.start > 0) {
+							switch (this.source[this.start-1]) {
+								case '.':
+									if (this.source[this.start-2] == '>')
+										// case of member type where enclosing type is parameterized
+										this.token = TYPE;
+									else
+										this.token = METHOD;
+									return this.token;
+								default:
+									this.token = TYPE;
+									return this.token;
+							}
+						} 
+						break;
+					case '(':
+						this.token = METHOD;
+						return this.token;
+					case ')':
+						this.start = ++this.index;
+						this.token = END;
+						return this.token;
+					case '#':
+						if (this.index == previousTokenEnd) {
+							this.start = this.index+1;
+							previousTokenEnd = this.start;
+						} else {
+							this.token = LOCAL_VAR;
+							return this.token;
+						}
+						break;
+					case Character.MIN_VALUE:
+						switch (this.token) {
+							case START:
+								this.token = PACKAGE;
+								break;
+							case METHOD:
+							case LOCAL_VAR:
+								this.token = LOCAL_VAR;
+								break;
+							case TYPE:
+								if (this.index > this.start && this.source[this.start-1] == '.')
+									this.token = FIELD;
+								else
+									this.token = END;
+								break;
+							default:
+								this.token = END;
+								break;
+						}
+						return this.token;
+					case '*':
+					case '+':
+					case '-':
+						this.index++;
+						this.token = WILDCARD;
+						return this.token;
+					case '!':
+						this.index++;
+						this.token = CAPTURE;
+						return this.token;
+				}
+				this.index++;
+			}
+			this.token = END;
+			return this.token;
+		}
+		
+		void skipMethodSignature() {
+			this.start = this.index;
+			int braket = 0;
+			while (this.index < this.source.length) {
+				switch (this.source[this.index]) {
+					case '#':
+					case '%':
+					case '^':
+						return;
+					case ':':
+						if (braket == 0)
+							return;
+						break;
+					case '<':
+					case '(':
+						braket++;
+						break;
+					case '>':
+					case ')':
+						braket--;
+						break;
+				}
+				this.index++;
+			}
+		}
+		
+		void skipParametersStart() {
+			if (this.index < this.source.length && this.source[this.index] == '<')
+				this.index++;
+		}
+		
+		void skipParametersEnd() {
+			while (this.index < this.source.length && this.source[this.index] != '>')
+				this.index++;
+			this.index++;
+		}
+		
+		void skipTypeEnd() {
+			if (this.index < this.source.length && this.source[this.index] == ';')
+				this.index++;
+		}
+		
+		public String toString() {
+			StringBuffer buffer = new StringBuffer();
+			switch (this.token) {
+				case START:
+					buffer.append("START: "); //$NON-NLS-1$
+					break;
+				case PACKAGE:
+					buffer.append("PACKAGE: "); //$NON-NLS-1$
+					break;
+				case TYPE:
+					buffer.append("TYPE: "); //$NON-NLS-1$
+					break;
+				case FIELD:
+					buffer.append("FIELD: "); //$NON-NLS-1$
+					break;
+				case METHOD:
+					buffer.append("METHOD: "); //$NON-NLS-1$
+					break;
+				case ARRAY:
+					buffer.append("ARRAY: "); //$NON-NLS-1$
+					break;
+				case LOCAL_VAR:
+					buffer.append("LOCAL VAR: "); //$NON-NLS-1$
+					break;
+				case FLAGS:
+					buffer.append("MODIFIERS: "); //$NON-NLS-1$
+					break;
+				case END:
+					buffer.append("END: "); //$NON-NLS-1$
+					break;
+			}
+			if (this.index < 0) {
+				buffer.append("**"); //$NON-NLS-1$
+				buffer.append(this.source);
+			} else if (this.index <= this.source.length) {
+				buffer.append(this.source, 0, this.start);
+				buffer.append('*');
+				if (this.start <= this.index) {
+					buffer.append(this.source, this.start, this.index - this.start);
+					buffer.append('*');
+					buffer.append(this.source, this.index, this.source.length - this.index);
+				} else {
+					buffer.append('*');
+					buffer.append(this.source, this.start, this.source.length - this.start);
+				}
+			} else {
+				buffer.append(this.source);
+				buffer.append("**"); //$NON-NLS-1$
+			}
+			return buffer.toString();
+		}
+	}
+	private boolean parsingPaused;
+	
+	private Scanner scanner;
+	
+	private boolean hasTypeName = true;
+	
+	public BindingKeyParser(BindingKeyParser parser) {
+		this(""); //$NON-NLS-1$
+		this.scanner = parser.scanner;
+	}
+	
+	public BindingKeyParser(String key) {
+		this.scanner = new Scanner(key.toCharArray());
+	}
+	
+	public void consumeArrayDimension(char[] brakets) {
+		// default is to do nothing
+	}
+	
+	public void consumeCapture() {
+		// default is to do nothing
+	}
+	
+	public void consumeField(char[] fieldName) {
+		// default is to do nothing
+	}
+	
+	public void consumeParameterizedMethod() {
+		// default is to do nothing
+	}
+	
+	public void consumeLocalType(char[] uniqueKey) {
+		// default is to do nothing
+	}
+	
+	public void consumeLocalVar(char[] varName) {
+		// default is to do nothing
+	}
+	
+	public void consumeMethod(char[] selector, char[] signature) {
+		// default is to do nothing
+	}
+	
+	public void consumeModifiers(char[] modifiers) {
+		// default is to do nothing
+	}
+	
+	public void consumeNonGenericType() {
+		// default is to do nothing
+	}
+
+	public void consumeMemberType(char[] simpleTypeName) {
+		// default is to do nothing
+	}
+
+	public void consumePackage(char[] pkgName) {
+		// default is to do nothing
+	}
+	
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		// default is to do nothing
+	}
+	
+	public void consumeParser(BindingKeyParser parser) {
+		// default is to do nothing
+	}
+	
+	public void consumeRawType() {
+		// default is to do nothing
+	}
+	
+	public void consumeScope(int scopeNumber) {
+		// default is to do nothing
+	}
+	
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		// default is to do nothing
+	}
+
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		// default is to do nothing
+	}
+
+	public void consumeTopLevelType() {
+		// default is to do nothing
+	}
+	
+	public void consumeType() {
+		// default is to do nothing
+	}
+	
+	public void consumeTypeParameter(char[] typeParameterName) {
+		// default is to do nothing
+	}
+	
+	public void consumeTypeVariable(char[] typeVariableName) {
+		// default is to do nothing
+	}
+	
+	public void consumeWildCard(int kind) {
+		// default is to do nothing
+	}
+	
+	/*
+	 * Returns the string that this binding key wraps.
+	 */
+	public String getKey() {
+		return new String(this.scanner.source);
+	}
+	
+	public boolean hasTypeName() {
+		return this.hasTypeName;
+	}
+	
+	public void malformedKey() {
+		// default is to do nothing
+	}
+	
+	public BindingKeyParser newParser() {
+		return new BindingKeyParser(this);
+	}
+	
+	public void parse() {
+		parse(false/*don't pause after fully qualified name*/);
+	}
+
+	public void parse(boolean pauseAfterFullyQualifiedName) {
+		if (!this.parsingPaused) {
+			// fully qualified name
+			parseFullyQualifiedName();
+			if (pauseAfterFullyQualifiedName) {
+				this.parsingPaused = true;
+				return;
+			}
+		}
+		if (!hasTypeName())
+			return;
+		consumeTopLevelType();
+		parseSecondaryType();
+		parseInnerType();
+		
+		if (this.scanner.isAtParametersStart()) {
+			this.scanner.skipParametersStart();
+			if (this.scanner.isAtTypeParameterStart())	{		
+				// generic type
+				parseGenericType();
+			 	// skip ";>"
+			 	this.scanner.skipParametersEnd();
+				// local type in generic type
+				parseInnerType();
+			} else if (this.scanner.isAtTypeArgumentStart())
+				// parameterized type
+				parseParameterizedType(null/*top level type*/, false/*no raw*/);
+			else if (this.scanner.isAtRawTypeEnd())
+				// raw type
+				parseRawType();
+		} else {
+			// non-generic type
+			consumeNonGenericType();
+		}
+		
+		consumeType();
+		this.scanner.skipTypeEnd();
+		parseFlags();
+		
+		if (this.scanner.isAtFieldOrMethodStart()) {
+			switch (this.scanner.nextToken()) {
+ 				case Scanner.FIELD:
+ 					consumeField(this.scanner.getTokenSource());
+					parseFlags();
+ 					return;
+ 				case Scanner.METHOD:
+ 					parseMethod();
+ 					if (this.scanner.isAtLocalVariableStart()) {
+ 						parseLocalVariable();
+ 					} else if (this.scanner.isAtMethodTypeVariableStart()) {
+						parseTypeVariable();
+					}
+			 		break;
+ 				default:
+ 					malformedKey();
+ 					return;
+			}
+		} else if (this.scanner.isAtTypeTypeVariableStart()) {
+			parseTypeVariable();
+		}
+	}
+	
+	private void parseFullyQualifiedName() {
+		switch(this.scanner.nextToken()) {
+			case Scanner.PACKAGE:
+				this.keyStart = 0;
+				consumePackage(this.scanner.getTokenSource());
+				this.hasTypeName = false;
+				return;
+			case Scanner.TYPE:
+				this.keyStart = this.scanner.start-1;
+				consumeFullyQualifiedName(this.scanner.getTokenSource());
+				break;
+	 		case Scanner.ARRAY:
+	 			this.keyStart = this.scanner.start;
+	 			consumeArrayDimension(this.scanner.getTokenSource());
+				if (this.scanner.nextToken() == Scanner.TYPE)
+	 				consumeFullyQualifiedName(this.scanner.getTokenSource());
+				else {
+					malformedKey();
+					return;
+				}
+				break;
+	 		case Scanner.WILDCARD:
+			 	char[] source = this.scanner.getTokenSource();
+			 	if (source.length == 0) {
+			 		malformedKey();
+			 		return;
+			 	}
+			 	int kind = -1;
+			 	switch (source[0]) {
+				 	case '*':
+				 		kind = Wildcard.UNBOUND;
+				 		break;
+				 	case '+':
+				 		kind = Wildcard.EXTENDS;
+				 		break;
+				 	case '-':
+				 		kind = Wildcard.SUPER;
+				 		break;
+			 	}
+			 	if (kind == -1) {
+			 		malformedKey();
+			 		return;
+			 	}
+			 	consumeWildCard(kind);
+			 	if (kind == Wildcard.UNBOUND) {
+			 		this.hasTypeName = false;
+			 		return;
+			 	}
+			 	parseFullyQualifiedName();
+	 			break;
+	 		case Scanner.CAPTURE:
+	 			consumeCapture();
+	 			parseFullyQualifiedName();
+	 			break;
+			default:
+	 			malformedKey();
+				return;
+		}
+	}
+	
+	private void parseParameterizedMethod() {
+		while (!this.scanner.isAtParametersEnd()) {
+			parseTypeArgument();
+		}
+		consumeParameterizedMethod();
+	}
+	
+	private void parseGenericType() {
+		while (!this.scanner.isAtParametersEnd()) {
+			if (this.scanner.nextToken() != Scanner.TYPE) {
+				malformedKey();
+				return;
+			}
+			consumeTypeParameter(this.scanner.getTokenSource());
+			this.scanner.skipTypeEnd();
+		}
+	}
+	
+	private void parseInnerType() {
+		if (!this.scanner.isAtMemberTypeStart() || this.scanner.nextToken() != Scanner.TYPE)
+			return;
+		char[] typeName = this.scanner.getTokenSource();
+	 	if (Character.isDigit(typeName[0])) {
+	 		// anonymous or local type
+	 		int nextToken = Scanner.TYPE;
+	 		while (this.scanner.isAtMemberTypeStart()) 
+	 			nextToken = this.scanner.nextToken();
+	 		typeName = nextToken == Scanner.END ? this.scanner.source : CharOperation.subarray(this.scanner.source, this.keyStart, this.scanner.index+1);
+	 		consumeLocalType(typeName);
+	 	} else {
+			consumeMemberType(typeName);
+			parseInnerType();
+	 	}
+	}
+	
+	private void parseLocalVariable() {
+	 	if (this.scanner.nextToken() != Scanner.LOCAL_VAR) {
+	 		malformedKey();
+			return;
+	 	}
+		char[] varName = this.scanner.getTokenSource();
+		if (Character.isDigit(varName[0])) {
+			int index = Integer.parseInt(new String(varName));
+			consumeScope(index);
+			if (!this.scanner.isAtLocalVariableStart()) {
+				malformedKey();
+				return;
+			}
+			parseLocalVariable();
+		} else {
+		 	consumeLocalVar(varName);
+			parseFlags();
+		}
+ 	}
+	
+	private void parseMethod() {
+	 	char[] selector = this.scanner.getTokenSource();
+	 	this.scanner.skipMethodSignature();
+	 	char[] signature = this.scanner.getTokenSource();
+	 	consumeMethod(selector, signature);
+		parseFlags();
+		if (this.scanner.isAtParametersStart())
+			parseParameterizedMethod();
+	}
+	
+	private void parseFlags() {
+		if (!this.scanner.isAtFlagsStart() || this.scanner.nextToken() != Scanner.FLAGS) return;
+		consumeModifiers(this.scanner.getTokenSource());
+	}
+	
+	private void parseParameterizedType(char[] typeName, boolean isRaw) {
+		if (!isRaw) {
+			while (!this.scanner.isAtParametersEnd()) {
+				parseTypeArgument();
+			}
+		}
+	 	// skip ";>"
+	 	this.scanner.skipParametersEnd();
+		consumeParameterizedType(typeName, isRaw);
+		this.scanner.skipTypeEnd();
+		parseFlags();
+	 	if (this.scanner.isAtMemberTypeStart() && this.scanner.nextToken() == Scanner.TYPE) {
+	 		typeName = this.scanner.getTokenSource();
+			if (this.scanner.isAtParametersStart()) {
+				this.scanner.skipParametersStart();
+		 		parseParameterizedType(typeName, this.scanner.isAtRawTypeEnd());
+			} else
+				consumeParameterizedType(typeName, true/*raw*/);
+	 	}
+	}
+	
+	private void parseRawType() {
+		this.scanner.skipParametersEnd();
+		consumeRawType();
+	}
+	
+	private void parseSecondaryType() {
+		if (!this.scanner.isAtSecondaryTypeStart() || this.scanner.nextToken() != Scanner.TYPE) return;
+		consumeSecondaryType(this.scanner.getTokenSource());
+	}
+	
+	private void parseTypeArgument() {
+		BindingKeyParser parser = newParser();
+		parser.parse();
+		consumeParser(parser);
+	}
+	
+	private void parseTypeVariable() {
+		if (this.scanner.nextToken() != Scanner.TYPE) {
+			malformedKey();
+			return;
+		}
+		consumeTypeVariable(this.scanner.getTokenSource());
+		this.scanner.skipTypeEnd();
+	}
+	
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
new file mode 100644
index 0000000..d5f21f9
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/BindingKeyResolver.java
@@ -0,0 +1,382 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
+import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+
+public class BindingKeyResolver extends BindingKeyParser {
+	Compiler compiler;
+	Binding compilerBinding;
+	
+	char[][] compoundName;
+	int dimension;
+	LookupEnvironment environment;
+	ReferenceBinding genericType;
+	MethodBinding methodBinding;
+	
+	CompilationUnitDeclaration parsedUnit;
+	BlockScope scope;
+	TypeBinding typeBinding;
+	TypeDeclaration typeDeclaration;
+	ArrayList types = new ArrayList();
+	
+	boolean isCapture;
+	int wildcardKind = -1;
+	
+	private BindingKeyResolver(BindingKeyParser parser, Compiler compiler, LookupEnvironment environment) {
+		super(parser);
+		this.compiler = compiler;
+		this.environment = environment;
+	}
+	
+	public BindingKeyResolver(String key) {
+		this(key, null, null);
+	}
+
+	public BindingKeyResolver(String key, Compiler compiler, LookupEnvironment environment) {
+		super(key);
+		this.compiler = compiler;
+		this.environment = environment;
+	}
+	
+	/*
+	 * If not already cached, computes and cache the compound name (pkg name + top level name) of this key.
+	 * Returns the package name if key is a pkg key.
+	 * Returns an empty array if malformed.
+	 * This key's scanner should be positioned on the package or type token.
+	 */
+	public char[][] compoundName() {
+		return this.compoundName;
+	}
+	 
+	public void consumeArrayDimension(char[] brakets) {
+		this.dimension = brakets.length;
+	}
+	
+	public void consumeCapture() {
+		this.isCapture = true;
+	}
+	
+	public void consumeField(char[] fieldName) {
+		FieldBinding[] fields = ((ReferenceBinding) this.typeBinding).fields();
+	 	for (int i = 0, length = fields.length; i < length; i++) {
+			FieldBinding field = fields[i];
+			if (CharOperation.equals(fieldName, field.name)) {
+				this.compilerBinding = field;
+				return;
+			}
+		}
+	}
+
+	public void consumeParameterizedMethod() {
+		TypeBinding[] arguments = getTypeBindingArguments();
+		if (arguments.length != this.methodBinding.typeVariables().length) return;
+	 	this.methodBinding = new ParameterizedGenericMethodBinding(this.methodBinding, arguments, this.environment);
+		this.compilerBinding = this.methodBinding;
+	}
+	
+	public void consumeLocalType(char[] uniqueKey) {
+ 		LocalTypeBinding[] localTypeBindings  = this.parsedUnit.localTypes;
+ 		for (int i = 0; i < this.parsedUnit.localTypeCount; i++)
+ 			if (CharOperation.equals(uniqueKey, localTypeBindings[i].computeUniqueKey(false/*without access flags*/))) {
+ 				this.typeBinding = localTypeBindings[i];
+				this.compilerBinding = this.typeBinding;
+ 				return;
+ 			}
+	}
+
+	public void consumeLocalVar(char[] varName) {
+		if (this.scope == null) {
+			this.scope = this.methodBinding.sourceMethod().scope;
+		}
+	 	for (int i = 0; i < this.scope.localIndex; i++) {
+			LocalVariableBinding local = this.scope.locals[i];
+			if (CharOperation.equals(varName, local.name)) {
+				this.compilerBinding = local;
+				return;
+			}
+		}
+	}
+
+	public void consumeMethod(char[] selector, char[] signature) {
+		MethodBinding[] methods = ((ReferenceBinding) this.typeBinding).methods();
+	 	for (int i = 0, methodLength = methods.length; i < methodLength; i++) {
+			MethodBinding method = methods[i];
+			if (CharOperation.equals(selector, method.selector) || (selector.length == 0 && method.isConstructor())) {
+				char[] methodSignature = method.original().genericSignature();
+				if (methodSignature == null)
+					methodSignature = method.signature();
+				if (CharOperation.equals(signature, methodSignature)) {
+					this.methodBinding = method;
+					this.compilerBinding = this.methodBinding;
+					return;
+				}
+			}
+		}
+	}
+	
+	public void consumeMemberType(char[] simpleTypeName) {
+		this.typeBinding = getTypeBinding(simpleTypeName);
+		this.compilerBinding = this.typeBinding;
+	}
+
+	public void consumePackage(char[] pkgName) {
+		this.compoundName = CharOperation.splitOn('/', pkgName);
+		this.compilerBinding = new PackageBinding(this.compoundName, null, this.environment);
+	}
+	
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		TypeBinding[] arguments = getTypeBindingArguments();
+		if (simpleTypeName != null) {
+			// parameterized member type
+			this.genericType = this.genericType.getMemberType(simpleTypeName);
+			if (!isRaw)
+				this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, (ReferenceBinding) this.typeBinding);
+			else
+				// raw type
+				this.typeBinding = this.environment.createRawType(this.genericType, (ReferenceBinding) this.typeBinding);
+		} else {
+			// parameterized top level type
+			this.genericType = (ReferenceBinding) this.typeBinding;
+			this.typeBinding = this.environment.createParameterizedType(this.genericType, arguments, null);
+		}
+		this.compilerBinding = this.typeBinding;
+	}
+	
+
+	public void consumeParser(BindingKeyParser parser) {
+		this.types.add(parser);
+	}
+	
+	public void consumeScope(int scopeNumber) {
+		if (this.scope == null) {
+			this.scope = this.methodBinding.sourceMethod().scope;
+		}
+		if (scopeNumber >= this.scope.subscopeCount)
+			return; // malformed key
+		this.scope = (BlockScope) this.scope.subscopes[scopeNumber];
+	}
+	
+	public void consumeRawType() {
+		if (this.typeBinding == null) return;
+		this.typeBinding = this.environment.createRawType((ReferenceBinding) this.typeBinding, null/*no enclosing type*/);
+	}
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		if (this.parsedUnit == null) return;
+		this.typeDeclaration = null; // start from the parsed unit
+		this.typeBinding = getTypeBinding(simpleTypeName);
+		this.compilerBinding = this.typeBinding;
+	}
+	
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		this.compoundName = CharOperation.splitOn('/', fullyQualifiedName);
+	}
+	
+	public void consumeTopLevelType() {
+		if (this.compoundName.length == 1 && this.compoundName[0].length == 1) {
+			// case of base type
+ 			TypeBinding baseTypeBinding = getBaseTypeBinding(this.compoundName[0]);
+ 			if (baseTypeBinding != null) {
+				this.typeBinding = baseTypeBinding;
+				this.compilerBinding = this.typeBinding;
+				return;
+ 			}
+		}
+		this.parsedUnit = getCompilationUnitDeclaration();
+		if (this.parsedUnit != null && this.compiler != null) {
+			this.compiler.process(this.parsedUnit, this.compiler.totalUnits+1); // noop if unit has already been resolved
+		}
+		if (this.parsedUnit == null) {
+			this.typeBinding = getBinaryBinding();
+			this.compilerBinding = this.typeBinding;
+		} else {
+			char[] typeName = this.compoundName[this.compoundName.length-1];
+			this.typeBinding = getTypeBinding(typeName);
+			this.compilerBinding = this.typeBinding;
+		}
+	}
+	
+	public void consumeType() {
+		this.typeBinding = getArrayBinding(this.dimension, this.typeBinding);
+		this.compilerBinding = this.typeBinding;
+	}
+	
+	public void consumeTypeVariable(char[] typeVariableName) {
+	 	TypeVariableBinding[] typeVariableBindings = this.methodBinding != null ? this.methodBinding.typeVariables() : this.typeBinding.typeVariables();
+	 	for (int i = 0, length = typeVariableBindings.length; i < length; i++) {
+			TypeVariableBinding typeVariableBinding = typeVariableBindings[i];
+			if (CharOperation.equals(typeVariableName, typeVariableBinding.sourceName())) {
+				this.compilerBinding = typeVariableBinding;
+				return;
+			}
+		}
+	}
+	
+	public void consumeWildCard(int kind) {
+		this.wildcardKind = kind;
+	}
+	
+	/*
+	 * If the given dimension is greater than 0 returns an array binding for the given type binding.
+	 * Otherwise return the given type binding.
+	 * Returns null if the given type binding is null.
+	 */
+	private TypeBinding getArrayBinding(int dim, TypeBinding binding) {
+		if (binding == null) return null;
+		if (dim == 0) return binding;
+		return this.environment.createArrayType(binding, dim);
+	}
+	
+	private TypeBinding getBaseTypeBinding(char[] signature) {
+		switch (signature[0]) {
+			case 'I' :
+				return BaseTypes.IntBinding;
+			case 'Z' :
+				return BaseTypes.BooleanBinding;
+			case 'V' :
+				return BaseTypes.VoidBinding;
+			case 'C' :
+				return BaseTypes.CharBinding;
+			case 'D' :
+				return BaseTypes.DoubleBinding;
+			case 'B' :
+				return BaseTypes.ByteBinding;
+			case 'F' :
+				return BaseTypes.FloatBinding;
+			case 'J' :
+				return BaseTypes.LongBinding;
+			case 'S' :
+				return BaseTypes.ShortBinding;
+			case 'N':
+				return BaseTypes.NullBinding;
+			default :
+				return null;
+		}
+	}
+	 
+	/*
+	 * Returns a binary binding corresonding to this key's compound name.
+	 * Returns null if not found.
+	 */
+	private TypeBinding getBinaryBinding() {
+		return this.environment.getType(this.compoundName);
+	}
+	 
+	/*
+	 * Finds the compilation unit declaration corresponding to the key in the given lookup environment.
+	 * Returns null if no compilation unit declaration could be found.
+	 * This key's scanner should be positioned on the package token.
+	 */
+	public CompilationUnitDeclaration getCompilationUnitDeclaration() {
+		char[][] name = compoundName();
+		if (name.length == 0) return null;
+		if (this.environment == null) return null;
+		ReferenceBinding binding = this.environment.getType(name);
+		if (!(binding instanceof SourceTypeBinding)) return null;
+		SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) binding;
+		if (sourceTypeBinding.scope == null) 
+			return null;
+		return sourceTypeBinding.scope.compilationUnitScope().referenceContext;
+	}
+	 
+	/*
+	 * Returns the compiler binding corresponding to this key.
+	 * Returns null is malformed.
+	 * This key's scanner should be positioned on the package token.
+	 */
+	public Binding getCompilerBinding() {
+		parse();
+		return this.compilerBinding;
+	}
+	
+	private TypeBinding getTypeBinding(char[] simpleTypeName) {
+		if (this.typeBinding instanceof BinaryTypeBinding) {
+			return ((BinaryTypeBinding) this.typeBinding).getMemberType(simpleTypeName);
+		} else {
+			TypeDeclaration[] typeDeclarations = 
+				this.typeDeclaration == null ? 
+					(this.parsedUnit == null ? null : this.parsedUnit.types) : 
+					this.typeDeclaration.memberTypes;
+			if (typeDeclarations == null) return null;
+			for (int i = 0, length = typeDeclarations.length; i < length; i++) {
+				TypeDeclaration declaration = typeDeclarations[i];
+				if (CharOperation.equals(simpleTypeName, declaration.name)) {
+					this.typeDeclaration = declaration;
+					return declaration.binding;
+				}
+			}
+		}
+		return null;
+	}
+	
+	private TypeBinding[] getTypeBindingArguments() {
+		int size = this.types.size();
+		TypeBinding[] arguments = new TypeBinding[size];
+		int rank = 0;
+		for (int i = 0; i < size; i++) {
+			BindingKeyResolver resolver = (BindingKeyResolver) this.types.get(i);
+			TypeBinding binding;
+			int kind = resolver.wildcardKind;
+			switch (kind) {
+				case Wildcard.EXTENDS:
+				case Wildcard.SUPER:
+					binding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, (TypeBinding) resolver.compilerBinding, null /*no extra bound*/, kind);
+					break;
+				case Wildcard.UNBOUND:
+					binding = this.environment.createWildcard((ReferenceBinding) this.typeBinding, rank++, null/*no bound*/, null /*no extra bound*/, kind);
+					break;
+				default:
+					binding = (TypeBinding) resolver.compilerBinding;
+			}
+			if (resolver.isCapture)
+				binding = new CaptureBinding((WildcardBinding) binding);
+			arguments[i] = binding;
+		}
+		this.types = new ArrayList();
+		return arguments;
+	}
+	 
+	public void malformedKey() {
+		this.compoundName = CharOperation.NO_CHAR_CHAR;
+	}
+	
+	public BindingKeyParser newParser() {
+		return new BindingKeyResolver(this, this.compiler, this.environment);
+	}
+	 
+	public String toString() {
+		return getKey();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java
index 55bf6c7..fb90197 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CharArrayBuffer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java
index 586a3aa..fb5b1cc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java
index 5a4e660..9b1916e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java
index 0893dfb..53a5f5c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileStruct.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
index 549a190..abb55f0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java
index badf6d1..656ef07 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeSnippetParsingUtil.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2002, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
index 2932b90..94046cc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderParser.java
@@ -1,16 +1,17 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.util;
 
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
@@ -67,7 +68,7 @@
 			
 			// do not report problem before last parsed comment while recovering code...
 			this.javadocParser.reportProblems = this.currentElement == null || commentSourceEnd > this.lastJavadocEnd;
-			deprecated = this.javadocParser.checkDeprecation(commentSourceStart, commentSourceEnd);
+			deprecated = this.javadocParser.checkDeprecation(lastCommentIndex);
 			this.javadoc = this.javadocParser.docComment;
 			break nextComment;
 		}
@@ -112,6 +113,24 @@
 		super.consumeInterfaceHeader();
 	}
 
+	protected void consumeInternalCompilationUnit() {
+		// InternalCompilationUnit ::= PackageDeclaration
+		// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+		// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+	}
+	protected void consumeInternalCompilationUnitWithTypes() {
+		// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+		// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+		// InternalCompilationUnit ::= TypeDeclarations
+		// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+		// consume type declarations
+		int length;
+		if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+			this.compilationUnit.types = new TypeDeclaration[length];
+			this.astPtr -= length;
+			System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+		}
+	}
 	/**
 	 * Insure that start position is always positive.
 	 * @see org.eclipse.jdt.internal.compiler.parser.Parser#containsComment(int, int)
@@ -182,9 +201,28 @@
 		if (index < 0) return position; // no obsolete comment
 		pushOnCommentsStack(0, index); // store comment before flushing them
 
-		if (validCount > 0){ // move valid comment infos, overriding obsolete comment infos
-			System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
-			System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);		
+		switch (validCount) {
+			case 0:
+				// do nothing
+				break;
+			// move valid comment infos, overriding obsolete comment infos
+			case 2:
+				this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+				this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+				this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+				this.scanner.commentStarts[1] = this.scanner.commentStarts[index+2];
+				this.scanner.commentStops[1] = this.scanner.commentStops[index+2];
+				this.scanner.commentTagStarts[1] = this.scanner.commentTagStarts[index+2];
+				break;
+			case 1:
+				this.scanner.commentStarts[0] = this.scanner.commentStarts[index+1];
+				this.scanner.commentStops[0] = this.scanner.commentStops[index+1];
+				this.scanner.commentTagStarts[0] = this.scanner.commentTagStarts[index+1];
+				break;
+			default:
+				System.arraycopy(this.scanner.commentStarts, index + 1, this.scanner.commentStarts, 0, validCount);
+				System.arraycopy(this.scanner.commentStops, index + 1, this.scanner.commentStops, 0, validCount);		
+				System.arraycopy(this.scanner.commentTagStarts, index + 1, this.scanner.commentTagStarts, 0, validCount);
 		}
 		this.scanner.commentPtr = validCount - 1;
 		return position;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderScanner.java
index 9c20bef..90a5464 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderScanner.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CommentRecorderScanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java
index c9e91fa..91c18d4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPool.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java
index 7384eaa..eac3181 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantPoolEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -40,6 +40,28 @@
 	private int utf8Length;
 	private char[] classInfoName;
 	
+	public ConstantPoolEntry() {
+		this.classInfoNameIndex = -1;
+		this.classIndex = -1;
+		this.nameAndTypeIndex = -1;
+		this.stringIndex = -1;
+		this.stringValue = null;
+		this.integerValue = -1;
+		this.floatValue = -0.0f;
+		this.doubleValue = -0-0;
+		this.longValue = -1;
+		this.nameAndTypeDescriptorIndex = -1;
+		this.nameAndTypeNameIndex = -1;
+		this.className = null;
+		this.fieldName = null;
+		this.methodName = null;
+		this.fieldDescriptor = null;
+		this.methodDescriptor = null;
+		this.utf8Value = null;
+		this.utf8Length = -1;
+		this.classInfoName = null;		
+	}
+	
 	/**
 	 * @see IConstantPoolEntry#getKind()
 	 */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java
index 014d4a2..bda70f9 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
new file mode 100644
index 0000000..b00e2e3
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import org.eclipse.jdt.core.IInitializer;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.ImportDeclaration;
+import org.eclipse.jdt.core.dom.Initializer;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.PackageDeclaration;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.internal.core.SourceRefElement;
+
+public class DOMFinder extends ASTVisitor {
+	
+	public ASTNode foundNode = null;
+	public IBinding foundBinding = null;
+	
+	private CompilationUnit ast;
+	private SourceRefElement element;
+	private boolean resolveBinding;
+	private int rangeStart = -1, rangeLength = 0;
+	
+	public DOMFinder(CompilationUnit ast, SourceRefElement element, boolean resolveBinding) {
+		this.ast = ast;
+		this.element = element;
+		this.resolveBinding = resolveBinding;
+	}
+	
+	protected boolean found(ASTNode node, ASTNode name) {
+		if (name.getStartPosition() == this.rangeStart && name.getLength() == this.rangeLength) {
+			this.foundNode = node;
+			return true;
+		}
+		return false;
+	}
+	
+	public ASTNode search() throws JavaModelException {
+		ISourceRange range = null;
+		if (this.element instanceof IMember && !(this.element instanceof IInitializer))
+			range = ((IMember) this.element).getNameRange();
+		else
+			range = this.element.getSourceRange();
+		this.rangeStart = range.getOffset();
+		this.rangeLength = range.getLength();
+		this.ast.accept(this);
+		return this.foundNode;
+	}
+	
+	public boolean visit(AnnotationTypeDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(AnnotationTypeMemberDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(AnonymousClassDeclaration node) {
+		ASTNode name;
+		ASTNode parent = node.getParent();
+		switch (parent.getNodeType()) {
+			case ASTNode.CLASS_INSTANCE_CREATION:
+				name = ((ClassInstanceCreation) parent).getType();
+				break;
+			case ASTNode.ENUM_CONSTANT_DECLARATION:
+				name = ((EnumConstantDeclaration) parent).getName();
+				break;
+			default:
+				return true;
+		}
+		if (found(node, name) && this.resolveBinding)
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(EnumConstantDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveVariable();
+		return true;
+	}
+	
+	public boolean visit(EnumDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(ImportDeclaration node) {
+		if (found(node, node) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(Initializer node) {
+		// note that no binding exists for an Initializer
+		found(node, node);
+		return true;
+	}
+	
+	public boolean visit(MethodDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(PackageDeclaration node) {
+		if (found(node, node) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(TypeDeclaration node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(TypeParameter node) {
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+	
+	public boolean visit(VariableDeclarationFragment node) {						
+		if (found(node, node.getName()) && this.resolveBinding) 
+			this.foundBinding = node.resolveBinding();
+		return true;
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
index 232f4fc..6632b61 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DefaultBytecodeVisitor.java
@@ -1,18 +1,23 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.util;
 
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
 import org.eclipse.jdt.core.util.IBytecodeVisitor;
+import org.eclipse.jdt.core.util.ICodeAttribute;
 import org.eclipse.jdt.core.util.IConstantPoolConstant;
 import org.eclipse.jdt.core.util.IConstantPoolEntry;
+import org.eclipse.jdt.core.util.ILocalVariableAttribute;
+import org.eclipse.jdt.core.util.ILocalVariableTableEntry;
 import org.eclipse.jdt.core.util.IOpcodeMnemonics;
 import org.eclipse.jdt.core.util.OpcodeStringValues;
 
@@ -34,12 +39,24 @@
 	private String lineSeparator;
 	private int tabNumber;
 	private int digitNumberForPC;
+    private ILocalVariableTableEntry[] localVariableTableEntries;
+    private int localVariableAttributeLength;
+	private int mode;
 	
-	public DefaultBytecodeVisitor(long codeLength, StringBuffer buffer, String lineSeparator, int tabNumber) {
+	public DefaultBytecodeVisitor(ICodeAttribute codeAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
+		ILocalVariableAttribute localVariableAttribute = codeAttribute.getLocalVariableAttribute();
+		this.localVariableAttributeLength = localVariableAttribute == null ? 0 : localVariableAttribute.getLocalVariableTableLength();
+		if (this.localVariableAttributeLength != 0) {
+			this.localVariableTableEntries = localVariableAttribute.getLocalVariableTable();
+		} else {
+            this.localVariableTableEntries = null;
+		}
 		this.buffer = buffer;
 		this.lineSeparator = lineSeparator;
 		this.tabNumber = tabNumber + 1;
+		long codeLength = codeAttribute.getCodeLength();
 		this.digitNumberForPC = Long.toString(codeLength).length();
+		this.mode = mode;
 	}
 	/**
 	 * @see IBytecodeVisitor#_aaload(int)
@@ -59,7 +76,7 @@
 			buffer.append(' ');
 		}
 		buffer.append(pc);
-		buffer.append(Util.bind("disassembler.indentation")); //$NON-NLS-1$		
+		buffer.append(Messages.disassembler_indentation); 
 	}
 
 	/**
@@ -85,7 +102,11 @@
 	 */
 	public void _aload_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_0]);
+		buffer.append(Messages.bind(Messages.classformat_load,
+			new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_0],
+				getLocalVariableName(pc, 0)
+			}));
 		writeNewLine();
 	}
 
@@ -94,7 +115,10 @@
 	 */
 	public void _aload_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_1]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -103,7 +127,10 @@
 	 */
 	public void _aload_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_2]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -112,7 +139,10 @@
 	 */
 	public void _aload_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_3]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -121,9 +151,10 @@
 	 */
 	public void _aload(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ALOAD],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -132,11 +163,12 @@
 	 */
 	public void _anewarray(int pc, int index, IConstantPoolEntry constantClass) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ANEWARRAY])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(returnConstantClassName(constantClass));
+		buffer
+			.append(Messages.bind(Messages.classformat_anewarray, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ANEWARRAY],
+				Integer.toString(index),
+				returnConstantClassName(constantClass)
+			})));
 		writeNewLine();
 	}
 
@@ -163,7 +195,10 @@
 	 */
 	public void _astore_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_0]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -172,16 +207,44 @@
 	 */
 	public void _astore_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_1]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
+	private String getLocalVariableName(int pc, int index) {
+        int nextPC = pc + 1;
+        switch(index) {
+            case 0 :
+            case 1 :
+            case 2 :
+            case 3 :
+                break;
+            default :
+                nextPC = index <= 255 ? pc + 2 : pc + 3;
+        }        
+        
+        for (int i = 0, max = this.localVariableAttributeLength; i < max; i++) {
+            final ILocalVariableTableEntry entry = this.localVariableTableEntries[i];
+            final int startPC = entry.getStartPC();
+            if (entry.getIndex() == index && (startPC <= nextPC) && ((startPC + entry.getLength()) > nextPC)) {
+                return new String(entry.getName());
+            }
+        }
+		String localVariableName = Messages.bind(Messages.disassembler_localvariablename, (new String[] {Integer.toString(index)})); 
+		return localVariableName;
+	}
 
 	/**
 	 * @see IBytecodeVisitor#_astore_2(int)
 	 */
 	public void _astore_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_2]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -190,7 +253,10 @@
 	 */
 	public void _astore_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_3]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -199,9 +265,10 @@
 	 */
 	public void _astore(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ASTORE],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -238,7 +305,7 @@
 	public void _bipush(int pc, byte _byte) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.BIPUSH])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(_byte);
 		writeNewLine();
 	}
@@ -266,11 +333,12 @@
 	 */
 	public void _checkcast(int pc, int index, IConstantPoolEntry constantClass) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.CHECKCAST])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(returnConstantClassName(constantClass));
+		buffer
+			.append(Messages.bind(Messages.classformat_checkcast, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.CHECKCAST],
+				Integer.toString(index),
+				returnConstantClassName(constantClass)
+			})));
 		writeNewLine();
 	}
 
@@ -378,7 +446,10 @@
 	 */
 	public void _dload_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_0]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -387,7 +458,10 @@
 	 */
 	public void _dload_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_1]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -396,7 +470,10 @@
 	 */
 	public void _dload_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_2]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 	
@@ -405,7 +482,10 @@
 	 */
 	public void _dload_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_3]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -414,9 +494,10 @@
 	 */
 	public void _dload(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DLOAD],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -461,7 +542,10 @@
 	 */
 	public void _dstore_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_0]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -470,7 +554,10 @@
 	 */
 	public void _dstore_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_1]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -479,7 +566,10 @@
 	 */
 	public void _dstore_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_2]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -488,7 +578,10 @@
 	 */
 	public void _dstore_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_3]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -497,9 +590,10 @@
 	 */
 	public void _dstore(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.DSTORE],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -679,7 +773,10 @@
 	 */
 	public void _fload_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_0]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -688,7 +785,10 @@
 	 */
 	public void _fload_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_1]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -697,7 +797,10 @@
 	 */
 	public void _fload_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_2]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -706,7 +809,10 @@
 	 */
 	public void _fload_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_3]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -715,9 +821,10 @@
 	 */
 	public void _fload(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FLOAD],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -762,7 +869,10 @@
 	 */
 	public void _fstore_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_0]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -771,7 +881,10 @@
 	 */
 	public void _fstore_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_1]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -780,7 +893,10 @@
 	 */
 	public void _fstore_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_2]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -789,7 +905,10 @@
 	 */
 	public void _fstore_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_3]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -798,9 +917,10 @@
 	 */
 	public void _fstore(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.FSTORE],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -818,16 +938,13 @@
 	 */
 	public void _getfield(int pc, int index, IConstantPoolEntry constantFieldref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETFIELD])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.getfield")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantFieldref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldName())
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldDescriptor())
-			.append(Util.bind("classformat.getfieldclose")); //$NON-NLS-1$
+		buffer.append(Messages.bind(Messages.classformat_getfield, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETFIELD],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			new String(constantFieldref.getFieldDescriptor())
+		})));
 		writeNewLine();
 	}
 
@@ -836,16 +953,13 @@
 	 */
 	public void _getstatic(int pc, int index, IConstantPoolEntry constantFieldref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETSTATIC])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.getstatic")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantFieldref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldName())
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldDescriptor())
-			.append(Util.bind("classformat.getstaticclose")); //$NON-NLS-1$
+		buffer.append(Messages.bind(Messages.classformat_getstatic, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GETSTATIC],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			new String(constantFieldref.getFieldDescriptor())
+		})));
 		writeNewLine();
 	}
 
@@ -855,7 +969,7 @@
 	public void _goto_w(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GOTO_W])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -866,7 +980,7 @@
 	public void _goto(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.GOTO])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -967,7 +1081,7 @@
 	public void _if_acmpeq(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ACMPEQ])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -978,7 +1092,7 @@
 	public void _if_acmpne(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ACMPNE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -989,7 +1103,7 @@
 	public void _if_icmpeq(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPEQ])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1000,7 +1114,7 @@
 	public void _if_icmpge(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPGE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1011,7 +1125,7 @@
 	public void _if_icmpgt(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPGT])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1022,7 +1136,7 @@
 	public void _if_icmple(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPLE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1033,7 +1147,7 @@
 	public void _if_icmplt(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPLT])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1044,7 +1158,7 @@
 	public void _if_icmpne(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IF_ICMPNE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1127,7 +1241,7 @@
 	public void _ifeq(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFEQ])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1138,7 +1252,7 @@
 	public void _ifge(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFGE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1149,7 +1263,7 @@
 	public void _ifgt(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFGT])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1160,7 +1274,7 @@
 	public void _ifle(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFLE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1171,7 +1285,7 @@
 	public void _iflt(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFLT])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1182,7 +1296,7 @@
 	public void _ifne(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFNE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1193,7 +1307,7 @@
 	public void _ifnonnull(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFNONNULL])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1204,7 +1318,7 @@
 	public void _ifnull(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IFNULL])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1214,11 +1328,12 @@
 	 */
 	public void _iinc(int pc, int index, int _const) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IINC])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(_const);
+		buffer.append(Messages.bind(Messages.classformat_iinc, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.IINC],
+			Integer.toString(index),
+			Integer.toString(_const),
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -1227,7 +1342,10 @@
 	 */
 	public void _iload_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_0]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -1236,7 +1354,10 @@
 	 */
 	public void _iload_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_1]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -1245,7 +1366,10 @@
 	 */
 	public void _iload_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_2]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -1254,7 +1378,10 @@
 	 */
 	public void _iload_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_3]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -1263,9 +1390,10 @@
 	 */
 	public void _iload(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ILOAD],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -1292,11 +1420,11 @@
 	 */
 	public void _instanceof(int pc, int index, IConstantPoolEntry constantClass) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INSTANCEOF])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(returnConstantClassName(constantClass));
+		buffer.append(Messages.bind(Messages.classformat_instanceof, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INSTANCEOF],
+			Integer.toString(index),
+			returnConstantClassName(constantClass)
+		})));
 		writeNewLine();
 	}
 
@@ -1310,17 +1438,27 @@
 		IConstantPoolEntry constantInterfaceMethodref) {
 
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE])
-			.append(Util.bind("classformat.nargs")) //$NON-NLS-1$
-			.append(nargs)
-			.append(Util.bind("classformat.interfacemethodrefindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.invokeinterfacemethod")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantInterfaceMethodref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantInterfaceMethodref.getMethodName())
-			.append(constantInterfaceMethodref.getMethodDescriptor())
-			.append(Util.bind("classformat.invokeinterfacemethodclose")); //$NON-NLS-1$
+		if (isCompact()) {
+			buffer.append(Messages.bind(Messages.classformat_invokeinterface_compact, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE],
+				Integer.toString(index),
+				Integer.toString(nargs),
+				Util.toString(
+					constantInterfaceMethodref.getClassName(),
+					constantInterfaceMethodref.getMethodName(),
+					constantInterfaceMethodref.getMethodDescriptor(),
+					true)
+			})));
+		} else {
+			buffer.append(Messages.bind(Messages.classformat_invokeinterface, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEINTERFACE],
+					Integer.toString(index),
+					Integer.toString(nargs),
+					returnDeclaringClassName(constantInterfaceMethodref),
+					new String(constantInterfaceMethodref.getMethodName()),
+					new String(constantInterfaceMethodref.getMethodDescriptor()),
+			})));
+		}
 		writeNewLine();
 	}
 
@@ -1329,15 +1467,25 @@
 	 */
 	public void _invokespecial(int pc, int index, IConstantPoolEntry constantMethodref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.invokespecialmethod")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantMethodref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantMethodref.getMethodName())
-			.append(constantMethodref.getMethodDescriptor())
-			.append(Util.bind("classformat.invokespecialmethodclose")); //$NON-NLS-1$
+		if (isCompact()) {
+			buffer.append(Messages.bind(Messages.classformat_invokespecial_compact, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL],
+				Integer.toString(index),
+				Util.toString(
+					constantMethodref.getClassName(),
+					constantMethodref.getMethodName(),
+					constantMethodref.getMethodDescriptor(),
+					true)
+			})));
+		} else {
+			buffer.append(Messages.bind(Messages.classformat_invokespecial, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESPECIAL],
+					Integer.toString(index),
+					returnDeclaringClassName(constantMethodref),
+					new String(constantMethodref.getMethodName()),
+					new String(constantMethodref.getMethodDescriptor()),
+			})));
+		}
 		writeNewLine();
 	}
 
@@ -1346,15 +1494,25 @@
 	 */
 	public void _invokestatic(int pc, int index, IConstantPoolEntry constantMethodref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.invokestaticmethod")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantMethodref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantMethodref.getMethodName())
-			.append(constantMethodref.getMethodDescriptor())
-			.append(Util.bind("classformat.invokestaticmethodclose")); //$NON-NLS-1$
+		if (isCompact()) {
+			buffer.append(Messages.bind(Messages.classformat_invokestatic_compact, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC],
+				Integer.toString(index),
+				Util.toString(
+					constantMethodref.getClassName(),
+					constantMethodref.getMethodName(),
+					constantMethodref.getMethodDescriptor(),
+					true)
+			})));
+		} else {
+			buffer.append(Messages.bind(Messages.classformat_invokestatic, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKESTATIC],
+				Integer.toString(index),
+				returnDeclaringClassName(constantMethodref),
+				new String(constantMethodref.getMethodName()),
+				new String(constantMethodref.getMethodDescriptor()),
+			})));
+		}
 		writeNewLine();
 	}
 
@@ -1363,15 +1521,25 @@
 	 */
 	public void _invokevirtual(int pc, int index, IConstantPoolEntry constantMethodref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.invokevirtualmethod")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantMethodref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantMethodref.getMethodName())
-			.append(constantMethodref.getMethodDescriptor())
-			.append(Util.bind("classformat.invokevirtualmethodclose")); //$NON-NLS-1$
+		if (isCompact()) {
+			buffer.append(Messages.bind(Messages.classformat_invokevirtual_compact, (new String[] {
+				OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL],
+				Integer.toString(index),
+				Util.toString(
+					constantMethodref.getClassName(),
+					constantMethodref.getMethodName(),
+					constantMethodref.getMethodDescriptor(),
+					true)
+			})));
+		} else {
+			buffer.append(Messages.bind(Messages.classformat_invokevirtual, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.INVOKEVIRTUAL],
+					Integer.toString(index),
+					returnDeclaringClassName(constantMethodref),
+					new String(constantMethodref.getMethodName()),
+					new String(constantMethodref.getMethodDescriptor()),
+			})));
+		}
 		writeNewLine();
 	}
 
@@ -1425,7 +1593,10 @@
 	 */
 	public void _istore_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_0]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -1434,7 +1605,10 @@
 	 */
 	public void _istore_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_1]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -1443,7 +1617,10 @@
 	 */
 	public void _istore_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_2]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -1452,7 +1629,10 @@
 	 */
 	public void _istore_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_3]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -1461,9 +1641,10 @@
 	 */
 	public void _istore(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.ISTORE],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -1500,7 +1681,7 @@
 	public void _jsr_w(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.JSR_W])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1511,7 +1692,7 @@
 	public void _jsr(int pc, int branchOffset) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.JSR])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(branchOffset + pc);
 		writeNewLine();
 	}
@@ -1611,22 +1792,34 @@
 	 */
 	public void _ldc_w(int pc, int index, IConstantPoolEntry constantPoolEntry) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")); //$NON-NLS-1$
 		switch (constantPoolEntry.getKind()) {
 			case IConstantPoolConstant.CONSTANT_Float :
-				appendOutputforConstantFloat(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_float, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					Float.toString(constantPoolEntry.getFloatValue())
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_Integer :
-				appendOutputforConstantInteger(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					Integer.toString(constantPoolEntry.getIntegerValue())
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_String :
-				appendOutputForConstantString(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_string, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					constantPoolEntry.getStringValue()
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_Class :
-				appendOutputForConstantClass(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_class, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC_W],
+					Integer.toString(index),
+					returnConstantClassName(constantPoolEntry)
+				})));
 		}
 		writeNewLine();
 	}
@@ -1636,22 +1829,34 @@
 	 */
 	public void _ldc(int pc, int index, IConstantPoolEntry constantPoolEntry) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")); //$NON-NLS-1$
 		switch (constantPoolEntry.getKind()) {
 			case IConstantPoolConstant.CONSTANT_Float :
-				appendOutputforConstantFloat(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_float, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					Float.toString(constantPoolEntry.getFloatValue())
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_Integer :
-				appendOutputforConstantInteger(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_integer, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					Integer.toString(constantPoolEntry.getIntegerValue())
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_String :
-				appendOutputForConstantString(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_string, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					constantPoolEntry.getStringValue()
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_Class :
-				appendOutputForConstantClass(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc_w_class, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC],
+					Integer.toString(index),
+					returnConstantClassName(constantPoolEntry)
+				})));
 		}
 		writeNewLine();
 	}
@@ -1661,16 +1866,20 @@
 	 */
 	public void _ldc2_w(int pc, int index, IConstantPoolEntry constantPoolEntry) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")); //$NON-NLS-1$
 		switch (constantPoolEntry.getKind()) {
 			case IConstantPoolConstant.CONSTANT_Long :
-				appendOutputForConstantLong(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc2_w_long, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W],
+					Integer.toString(index),
+					Long.toString(constantPoolEntry.getLongValue())
+				})));
 				break;
 			case IConstantPoolConstant.CONSTANT_Double :
-				appendOutputForConstantDouble(constantPoolEntry);
+				buffer.append(Messages.bind(Messages.classformat_ldc2_w_double, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LDC2_W],
+					Integer.toString(index),
+					Double.toString(constantPoolEntry.getDoubleValue())
+				})));
 		}
 		writeNewLine();
 	}
@@ -1689,7 +1898,10 @@
 	 */
 	public void _lload_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_0]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -1698,7 +1910,10 @@
 	 */
 	public void _lload_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_1]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -1707,7 +1922,10 @@
 	 */
 	public void _lload_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_2]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -1716,7 +1934,10 @@
 	 */
 	public void _lload_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_3]);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -1725,9 +1946,10 @@
 	 */
 	public void _lload(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_load, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LLOAD],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -1819,7 +2041,10 @@
 	 */
 	public void _lstore_0(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_0]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_0],
+			getLocalVariableName(pc, 0)
+		})));
 		writeNewLine();
 	}
 
@@ -1828,7 +2053,10 @@
 	 */
 	public void _lstore_1(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_1]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_1],
+			getLocalVariableName(pc, 1)
+		})));
 		writeNewLine();
 	}
 
@@ -1837,7 +2065,10 @@
 	 */
 	public void _lstore_2(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_2]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_2],
+			getLocalVariableName(pc, 2)
+		})));
 		writeNewLine();
 	}
 
@@ -1846,7 +2077,10 @@
 	 */
 	public void _lstore_3(int pc) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_3]);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE_3],
+			getLocalVariableName(pc, 3)
+		})));
 		writeNewLine();
 	}
 
@@ -1855,9 +2089,10 @@
 	 */
 	public void _lstore(int pc, int index) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(index);
+		buffer.append(Messages.bind(Messages.classformat_store, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.LSTORE],
+			getLocalVariableName(pc, index)
+		})));
 		writeNewLine();
 	}
 
@@ -1915,12 +2150,12 @@
 		int dimensions,
 		IConstantPoolEntry constantClass) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.MULTIANEWARRAY])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(returnConstantClassName(constantClass));
-		appendDimensions(dimensions);
+		buffer.append(Messages.bind(Messages.classformat_multianewarray, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.MULTIANEWARRAY],
+			Integer.toString(index),
+			returnConstantClassName(constantClass),
+			appendDimensions(dimensions)
+		})));
 		writeNewLine();
 	}
 
@@ -1929,11 +2164,11 @@
 	 */
 	public void _new(int pc, int index, IConstantPoolEntry constantClass) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEW])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(returnConstantClassName(constantClass));
+		buffer.append(Messages.bind(Messages.classformat_new, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEW],
+			Integer.toString(index),
+			returnConstantClassName(constantClass)
+		})));
 		writeNewLine();
 	}
 
@@ -1942,11 +2177,55 @@
 	 */
 	public void _newarray(int pc, int atype) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(atype)
-			.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-		appendGetArrayType(atype);
+		switch(atype) {
+			case T_BOOLEAN :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_boolean, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_CHAR :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_char, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_FLOAT :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_float, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_DOUBLE :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_double, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_BYTE :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_byte, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_SHORT :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_short, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_INT :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_int, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+				break;
+			case T_LONG :
+				this.buffer.append(Messages.bind(Messages.classformat_newarray_long, (new String[] {
+					OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.NEWARRAY],
+					Integer.toString(atype)
+				})));
+		}
 		writeNewLine();
 	}
 
@@ -1982,16 +2261,13 @@
 	 */
 	public void _putfield(int pc, int index, IConstantPoolEntry constantFieldref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTFIELD])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.putfield"))			 //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantFieldref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldName())
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldDescriptor())
-			.append(Util.bind("classformat.putfieldclose")); //$NON-NLS-1$
+		buffer.append(Messages.bind(Messages.classformat_putfield, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTFIELD],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			new String(constantFieldref.getFieldDescriptor())
+		})));
 		writeNewLine();
 	}
 
@@ -2000,16 +2276,13 @@
 	 */
 	public void _putstatic(int pc, int index, IConstantPoolEntry constantFieldref) {
 		dumpPcNumber(pc);
-		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTSTATIC])
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-			.append(index)
-			.append(Util.bind("classformat.putstatic")) //$NON-NLS-1$
-			.append(returnDeclaringClassName(constantFieldref))
-			.append(Util.bind("disassembler.classmemberseparator")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldName())
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(constantFieldref.getFieldDescriptor())
-			.append(Util.bind("classformat.putstaticclose")); //$NON-NLS-1$
+		buffer.append(Messages.bind(Messages.classformat_putstatic, (new String[] {
+			OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.PUTSTATIC],
+			Integer.toString(index),
+			returnDeclaringClassName(constantFieldref),
+			new String(constantFieldref.getFieldName()),
+			new String(constantFieldref.getFieldDescriptor())
+		})));
 		writeNewLine();
 	}
 
@@ -2019,7 +2292,7 @@
 	public void _ret(int pc, int index) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.RET])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(index);
 		writeNewLine();
 	}
@@ -2057,7 +2330,7 @@
 	public void _sipush(int pc, short value) {
 		dumpPcNumber(pc);
 		buffer.append(OpcodeStringValues.BYTECODE_NAMES[IOpcodeMnemonics.SIPUSH])
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+			.append(Messages.disassembler_space) 
 			.append(value);
 		writeNewLine();
 	}
@@ -2177,109 +2450,59 @@
 		writeNewLine();
 	}
 
-	private void appendDimensions(int dimensions) {
+	private String appendDimensions(int dimensions) {
+		StringBuffer stringBuffer = new StringBuffer();
 		for (int i = 0; i < dimensions; i++) {
-			this.buffer.append(Util.bind("disassembler.arraydimensions")); //$NON-NLS-1$
+			stringBuffer.append(Messages.disassembler_arraydimensions); 
 		}
+		return String.valueOf(stringBuffer);
 	}
-	
-	private void appendGetArrayType(int atype) {
-		switch(atype) {
-			case T_BOOLEAN :
-				this.buffer.append("boolean"); //$NON-NLS-1$
-				break;
-			case T_CHAR :
-				this.buffer.append("char"); //$NON-NLS-1$
-				break;
-			case T_FLOAT :
-				this.buffer.append("float"); //$NON-NLS-1$
-				break;
-			case T_DOUBLE :
-				this.buffer.append("double"); //$NON-NLS-1$
-				break;
-			case T_BYTE :
-				this.buffer.append("byte"); //$NON-NLS-1$
-				break;
-			case T_SHORT :
-				this.buffer.append("short"); //$NON-NLS-1$
-				break;
-			case T_INT :
-				this.buffer.append("int"); //$NON-NLS-1$
-				break;
-			case T_LONG :
-				this.buffer.append("long"); //$NON-NLS-1$
-		}
+
+	private boolean isCompact() {
+		return (this.mode & ClassFileBytesDisassembler.COMPACT) != 0;
 	}
 
 	private String returnConstantClassName(IConstantPoolEntry constantClass) {
 		char[] classInfoName = constantClass.getClassInfoName();
 		if (classInfoName.length == 0) {
 			return EMPTY_CLASS_NAME;
+		} else if (isCompact()) {
+			int lastIndexOfSlash = CharOperation.lastIndexOf('/', classInfoName);
+			if (lastIndexOfSlash != -1) {
+				return new String(classInfoName, lastIndexOfSlash + 1, classInfoName.length - lastIndexOfSlash - 1);
+			}
+			return new String(classInfoName);
 		} else {
 			return new String(classInfoName);
 		}
 	}
 
 	private String returnDeclaringClassName(IConstantPoolEntry constantRef) {
+		if (isCompact()) {
+			char[] className = constantRef.getClassName();
+			int lastIndexOfSlash = CharOperation.lastIndexOf('/', className);
+			if (lastIndexOfSlash != -1) {
+				return new String(className, lastIndexOfSlash + 1, className.length - lastIndexOfSlash - 1);
+			}
+			return new String(constantRef.getClassName());
+		}
 		return new String(constantRef.getClassName());
 	}
 
-	private void appendOutputForConstantDouble(IConstantPoolEntry constantPoolEntry) {
-		this.buffer
-			.append("<Double ") //$NON-NLS-1$
-			.append(constantPoolEntry.getDoubleValue())
-			.append(">"); //$NON-NLS-1$
-	}
-
-	private void appendOutputForConstantLong(IConstantPoolEntry constantPoolEntry) {
-		this.buffer
-			.append("<Long ") //$NON-NLS-1$
-			.append(constantPoolEntry.getLongValue())
-			.append(">"); //$NON-NLS-1$
-	}
-
-	private void appendOutputForConstantString(IConstantPoolEntry constantPoolEntry) {
-		this.buffer
-			.append("<String \"") //$NON-NLS-1$
-			.append(constantPoolEntry.getStringValue())
-			.append("\">"); //$NON-NLS-1$
-	}
-
-	private void appendOutputforConstantInteger(IConstantPoolEntry constantPoolEntry) {
-		this.buffer
-			.append("<Integer ") //$NON-NLS-1$
-			.append(constantPoolEntry.getIntegerValue())
-			.append(">"); //$NON-NLS-1$
-	}
-
-	private void appendOutputforConstantFloat(IConstantPoolEntry constantPoolEntry) {
-		this.buffer
-			.append("<Float ") //$NON-NLS-1$
-			.append(constantPoolEntry.getFloatValue())
-			.append(">"); //$NON-NLS-1$
-	}
-	
-	private void appendOutputForConstantClass(IConstantPoolEntry constantPoolEntry) {
-		this.buffer
-			.append("<Class ") //$NON-NLS-1$
-			.append(returnConstantClassName(constantPoolEntry))
-			.append(">"); //$NON-NLS-1$
-	}
-
 	private void writeNewLine() {
 		this.buffer.append(lineSeparator);
 	}	
 
 	private void writeTabs() {
 		for (int i = 0, max = this.tabNumber; i < max; i++) {
-			this.buffer.append(Util.bind("disassembler.indentation")); //$NON-NLS-1$
+			this.buffer.append(Messages.disassembler_indentation); 
 		}
 	}	
 
 	private void writeExtraTabs(int extraTabs) {
 		for (int i = 0, max = this.tabNumber + extraTabs; i < max; i++) {
-			this.buffer.append(Util.bind("disassembler.indentation")); //$NON-NLS-1$
+			this.buffer.append(Messages.disassembler_indentation); 
 		}
 	}	
 
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index 72e2eaa..ddf744c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -39,278 +39,75 @@
  */
 public class Disassembler extends ClassFileBytesDisassembler {
 
-	private static final char[] ANY_EXCEPTION = Util.bind("classfileformat.anyexceptionhandler").toCharArray();	 //$NON-NLS-1$
+	private static final char[] ANY_EXCEPTION = Messages.classfileformat_anyexceptionhandler.toCharArray();	 
 	private static final String EMPTY_OUTPUT = ""; //$NON-NLS-1$
 	private static final String VERSION_UNKNOWN = "unknown";//$NON-NLS-1$
 
+	private boolean appendModifier(StringBuffer buffer, int accessFlags, int modifierConstant, String modifier, boolean firstModifier) {
+		if ((accessFlags & modifierConstant) != 0) {		
+			if (!firstModifier) {
+				buffer.append(Messages.disassembler_space); 
+			}
+			if (firstModifier) {
+				firstModifier = false;
+			}
+			buffer.append(modifier);
+		}
+		return firstModifier;
+	}
+	
 	private void decodeModifiersForField(StringBuffer buffer, int accessFlags) {
 		boolean firstModifier = true;
-		if ((accessFlags & IModifierConstants.ACC_FINAL) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("final"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PRIVATE) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("private"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PROTECTED) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("protected"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PUBLIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("public"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_STATIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("static"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_TRANSIENT) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("transient"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_VOLATILE) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("volatile"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_ENUM) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("enum"); //$NON-NLS-1$
-		}
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PROTECTED, "protected", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PRIVATE, "private", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STATIC, "static", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_TRANSIENT, "transient", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_VOLATILE, "volatile", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ENUM, "enum", firstModifier); //$NON-NLS-1$
 		if (!firstModifier) {
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 		}
 	}	
 
 	private final void decodeModifiersForInnerClasses(StringBuffer buffer, int accessFlags) {
 		boolean firstModifier = true;
-		if ((accessFlags & IModifierConstants.ACC_PUBLIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("public"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PRIVATE) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("private"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PROTECTED) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("protected"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_STATIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("static"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_FINAL) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("final"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_ABSTRACT) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("abstract"); //$NON-NLS-1$
-		}
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PROTECTED, "protected", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PRIVATE, "private", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ABSTRACT, "abstract", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STATIC, "static", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); //$NON-NLS-1$
 		if (!firstModifier) {
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 		}
 	}
 
 	private final void decodeModifiersForMethod(StringBuffer buffer, int accessFlags) {
 		boolean firstModifier = true;
-		if ((accessFlags & IModifierConstants.ACC_ABSTRACT) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("abstract"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_FINAL) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("final"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_NATIVE) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("native"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PRIVATE) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("private"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PROTECTED) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("protected"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PUBLIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("public"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_STATIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("static"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_STRICT) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("strictfp"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_SYNCHRONIZED) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("synchronized"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_BRIDGE) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("bridge"); //$NON-NLS-1$
-		}		
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PROTECTED, "protected", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PRIVATE, "private", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ABSTRACT, "abstract", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STATIC, "static", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_SYNCHRONIZED, "synchronized", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_NATIVE, "native", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_STRICT, "strictfp", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_BRIDGE, "bridge", firstModifier); //$NON-NLS-1$
 		if (!firstModifier) {
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 		}
 	}
 
 	private final void decodeModifiersForType(StringBuffer buffer, int accessFlags) {
 		boolean firstModifier = true;
-		if ((accessFlags & IModifierConstants.ACC_ABSTRACT) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("abstract"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_FINAL) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("final"); //$NON-NLS-1$
-		}
-		if ((accessFlags & IModifierConstants.ACC_PUBLIC) != 0) {
-			if (!firstModifier) {
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
-			}
-			if (firstModifier) {
-				firstModifier = false;
-			}
-			buffer.append("public"); //$NON-NLS-1$
-		}
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_PUBLIC, "public", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_ABSTRACT, "abstract", firstModifier); //$NON-NLS-1$
+		firstModifier = appendModifier(buffer, accessFlags, IModifierConstants.ACC_FINAL, "final", firstModifier); //$NON-NLS-1$
 		if (!firstModifier) {
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 		}
 	}
 
@@ -397,29 +194,26 @@
 		final int typeIndex = annotation.getTypeIndex();
 		final char[] typeName = CharOperation.replaceOnCopy(annotation.getTypeName(), '/', '.');
 		buffer.append(
-			Util.bind("disassembler.annotationentrystart", //$NON-NLS-1$
-			new String[] {
+			Messages.bind(Messages.disassembler_annotationentrystart, new String[] {
 				Integer.toString(typeIndex),
 				new String(Signature.toCharArray(typeName))
-			}
-		));
+			}));
 		final IAnnotationComponent[] components = annotation.getComponents();
 		for (int i = 0, max = components.length; i < max; i++) {
 			disassemble(components[i], buffer, lineSeparator, tabNumber + 1);
 		}
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.annotationentryend")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_annotationentryend); 
 	}
 
 	private void disassemble(IAnnotationComponent annotationComponent, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
 		buffer.append(
-			Util.bind("disassembler.annotationcomponent", //$NON-NLS-1$
-			new String[] {
-				Integer.toString(annotationComponent.getComponentNameIndex()),
-				new String(annotationComponent.getComponentName())
-			}
-		));
+			Messages.bind(Messages.disassembler_annotationcomponent,
+				new String[] {
+					Integer.toString(annotationComponent.getComponentNameIndex()),
+					new String(annotationComponent.getComponentName())
+				}));
 		disassemble(annotationComponent.getComponentValue(), buffer, lineSeparator, tabNumber + 1);
 	}
 
@@ -467,51 +261,51 @@
 					case IConstantPoolConstant.CONSTANT_Utf8:
 						value = "\"" + decodeStringValue(constantPoolEntry.getUtf8Value()) + "\"";//$NON-NLS-1$//$NON-NLS-2$
 				}
-				buffer.append(Util.bind("disassembler.annotationdefaultvalue", value)); //$NON-NLS-1$
+				buffer.append(Messages.bind(Messages.disassembler_annotationdefaultvalue, value)); 
 				break;
 			case IAnnotationComponentValue.ENUM_TAG:
 				final int enumConstantTypeNameIndex = annotationComponentValue.getEnumConstantTypeNameIndex();
 				final char[] typeName = CharOperation.replaceOnCopy(annotationComponentValue.getEnumConstantTypeName(), '/', '.');
 				final int enumConstantNameIndex = annotationComponentValue.getEnumConstantNameIndex();
 				final char[] constantName = annotationComponentValue.getEnumConstantName();
-				buffer.append(Util.bind("disassembler.annotationenumvalue", //$NON-NLS-1$
+				buffer.append(Messages.bind(Messages.disassembler_annotationenumvalue,
 					new String[] {
 						Integer.toString(enumConstantTypeNameIndex),
 						Integer.toString(enumConstantNameIndex),
 						new String(Signature.toCharArray(typeName)),
 						new String(constantName)
-				})); //$NON-NLS-1$
+					}));
 				break;
 			case IAnnotationComponentValue.CLASS_TAG:
 				final int classIndex = annotationComponentValue.getClassInfoIndex();
 				constantPoolEntry = annotationComponentValue.getClassInfo();
 				final char[] className = CharOperation.replaceOnCopy(constantPoolEntry.getUtf8Value(), '/', '.');
-				buffer.append(Util.bind("disassembler.annotationclassvalue", //$NON-NLS-1$
+				buffer.append(Messages.bind(Messages.disassembler_annotationclassvalue,
 					new String[] {
 						Integer.toString(classIndex),
 						new String(Signature.toCharArray(className))
-				})); //$NON-NLS-1$
+					}));
 				break;
 			case IAnnotationComponentValue.ANNOTATION_TAG:
-				buffer.append(Util.bind("disassembler.annotationannotationvalue")); //$NON-NLS-1$
+				buffer.append(Messages.disassembler_annotationannotationvalue); 
 				IAnnotation annotation = annotationComponentValue.getAnnotationValue();
 				disassemble(annotation, buffer, lineSeparator, tabNumber + 1);
 				break;
 			case IAnnotationComponentValue.ARRAY_TAG:
-				buffer.append(Util.bind("disassembler.annotationarrayvaluestart")); //$NON-NLS-1$
+				buffer.append(Messages.disassembler_annotationarrayvaluestart); 
 				final IAnnotationComponentValue[] annotationComponentValues = annotationComponentValue.getAnnotationComponentValues();
 				for (int i = 0, max = annotationComponentValues.length; i < max; i++) {
 					writeNewLine(buffer, lineSeparator, tabNumber + 1);
 					disassemble(annotationComponentValues[i], buffer, lineSeparator, tabNumber + 1);
 				}
 				writeNewLine(buffer, lineSeparator, tabNumber + 1);
-				buffer.append(Util.bind("disassembler.annotationarrayvalueend")); //$NON-NLS-1$
+				buffer.append(Messages.disassembler_annotationarrayvalueend); 
 		}
 	}
 	
 	private void disassemble(IAnnotationDefaultAttribute annotationDefaultAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.annotationdefaultheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_annotationdefaultheader); 
 		IAnnotationComponentValue componentValue = annotationDefaultAttribute.getMemberValue();
 		writeNewLine(buffer, lineSeparator, tabNumber + 2);
 		disassemble(componentValue, buffer, lineSeparator, tabNumber + 1);
@@ -519,12 +313,11 @@
 
 	private void disassemble(IClassFileAttribute classFileAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.genericattributeheader")); //$NON-NLS-1$
-		buffer
-			.append(Util.bind("disassembler.genericattributename")) //$NON-NLS-1$
-			.append(classFileAttribute.getAttributeName())
-			.append(Util.bind("disassembler.genericattributelength")) //$NON-NLS-1$
-			.append(classFileAttribute.getAttributeLength());
+		buffer.append(Messages.bind(Messages.disassembler_genericattributeheader,
+			new String[] {
+				new String(classFileAttribute.getAttributeName()),
+				Long.toString(classFileAttribute.getAttributeLength())
+			}));
 	}
 
 	/**
@@ -541,38 +334,30 @@
 		IClassFileAttribute runtimeVisibleParameterAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS);
 		IClassFileAttribute runtimeInvisibleParameterAnnotationsAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS);
 		IClassFileAttribute annotationDefaultAttribute = Util.getAttribute(methodInfo, IAttributeNamesConstants.ANNOTATION_DEFAULT);
-		if (mode == DETAILED || mode == SYSTEM) {
-			buffer
-				.append(Util.bind("disassembler.begincommentline")) //$NON-NLS-1$
-				.append(Util.bind("classfileformat.methoddescriptor")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
-				.append(methodInfo.getDescriptorIndex())
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-				.append(methodDescriptor);
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			buffer.append(Messages.bind(Messages.classfileformat_methoddescriptor,
+				new String[] {
+					Integer.toString(methodInfo.getDescriptorIndex()),
+					new String(methodDescriptor)
+				}));
 			if (methodInfo.isDeprecated()) {
-				buffer.append(Util.bind("disassembler.deprecated"));//$NON-NLS-1$
+				buffer.append(Messages.disassembler_deprecated);
 			}			
 			writeNewLine(buffer, lineSeparator, tabNumber);
 			if (signatureAttribute != null) {
-				buffer
-					.append(Util.bind("disassembler.begincommentline"))	 //$NON-NLS-1$
-					.append(Util.bind("disassembler.signatureattributeheader")) //$NON-NLS-1$
-					.append(signatureAttribute.getSignature());
+				buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature())));
 				writeNewLine(buffer, lineSeparator, tabNumber);
 			}
 			if (codeAttribute != null) {
-				buffer
-					.append(Util.bind("disassembler.begincommentline")) //$NON-NLS-1$
-					.append(Util.bind("classfileformat.maxStack")) //$NON-NLS-1$
-					.append(codeAttribute.getMaxStack())
-					.append(Util.bind("disassembler.comma"))//$NON-NLS-1$
-					.append(Util.bind("disassembler.space"))//$NON-NLS-1$
-					.append(Util.bind("classfileformat.maxLocals")) //$NON-NLS-1$
-					.append(codeAttribute.getMaxLocals());
+				buffer.append(Messages.bind(Messages.classfileformat_stacksAndLocals,
+					new String[] {
+						Integer.toString(codeAttribute.getMaxStack()),
+						Integer.toString(codeAttribute.getMaxLocals())
+					}));
 				writeNewLine(buffer, lineSeparator, tabNumber);
 			}
 		}
-		if (mode == DETAILED) {
+		if (checkMode(mode, DETAILED)) {
 			// disassemble compact version of annotations
 			if (runtimeInvisibleAnnotationsAttribute != null) {
 				disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber + 1);
@@ -587,16 +372,15 @@
 		decodeModifiersForMethod(buffer, accessFlags);
 		if (methodInfo.isSynthetic()) {
 			buffer.append("synthetic"); //$NON-NLS-1$
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 		}
 		CharOperation.replace(methodDescriptor, '/', '.');
-		char[] methodName = null;
+		char[] methodName;
 		if (methodInfo.isConstructor()) {
 			methodName = classFileReader.getClassName();
 			buffer.append(Signature.toCharArray(methodDescriptor, methodName, getParameterNames(methodDescriptor, codeAttribute, accessFlags) , false, false, (accessFlags & IModifierConstants.ACC_VARARGS) != 0));
 		} else if (methodInfo.isClinit()) {
-			methodName = Util.bind("classfileformat.clinitname").toCharArray(); //$NON-NLS-1$
-			buffer.append(methodName);
+			buffer.append(Messages.bind(Messages.classfileformat_clinitname));
 		} else {
 			methodName = methodInfo.getName();
 			buffer.append(Signature.toCharArray(methodDescriptor, methodName, getParameterNames(methodDescriptor, codeAttribute, accessFlags) , false, true, (accessFlags & IModifierConstants.ACC_VARARGS) != 0));
@@ -611,27 +395,27 @@
 				CharOperation.replace(exceptionName, '/', '.');
 				buffer
 					.append(exceptionName)
-					.append(Util.bind("disassembler.comma"))//$NON-NLS-1$
-					.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+					.append(Messages.disassembler_comma)
+					.append(Messages.disassembler_space); 
 			}
 			char[] exceptionName = exceptionNames[length - 1];
 			CharOperation.replace(exceptionName, '/', '.');
 			buffer.append(exceptionName);
 		}
-		if (mode == DETAILED) {
+		if (checkMode(mode, DETAILED)) {
 			if (annotationDefaultAttribute != null) {
 				buffer.append(" default "); //$NON-NLS-1$
 				disassembleAsModifier((IAnnotationDefaultAttribute) annotationDefaultAttribute, buffer, lineSeparator, tabNumber);
 			}
 		}
-		buffer.append(Util.bind("disassembler.endofmethodheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_endofmethodheader); 
 		
-		if (mode == DETAILED || mode == SYSTEM) {
+		if (checkMode(mode, SYSTEM | DETAILED)) {
 			if (codeAttribute != null) {
-				disassemble(codeAttribute, buffer, lineSeparator, tabNumber);
+				disassemble(codeAttribute, buffer, lineSeparator, tabNumber, mode);
 			}
 		}
-		if (mode == SYSTEM) {
+		if (checkMode(mode, SYSTEM)) {
 			IClassFileAttribute[] attributes = methodInfo.getAttributes();
 			int length = attributes.length;
 			if (length != 0) {
@@ -696,12 +480,12 @@
 		IClassFileAttribute classFileAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.SIGNATURE);
 		ISignatureAttribute signatureAttribute = (ISignatureAttribute) classFileAttribute;
 		final int accessFlags = classFileReader.getAccessFlags();
-		if (mode == DETAILED || mode == SYSTEM) {
+		if (checkMode(mode, SYSTEM | DETAILED)) {
 			int minorVersion = classFileReader.getMinorVersion();
 			int majorVersion = classFileReader.getMajorVersion();
-			buffer.append(Util.bind("disassembler.begincommentline")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_begincommentline); 
 			if (sourceAttribute != null) {
-				buffer.append(Util.bind("disassembler.sourceattributeheader")); //$NON-NLS-1$
+				buffer.append(Messages.disassembler_sourceattributeheader); 
 				buffer.append(sourceAttribute.getSourceFileName());
 			}
 			String versionNumber = VERSION_UNKNOWN;//$NON-NLS-1$
@@ -717,22 +501,19 @@
 				versionNumber = JavaCore.VERSION_1_5;
 			}
 			buffer.append(
-				Util.bind("classfileformat.versiondetails",//$NON-NLS-1$
+				Messages.bind(Messages.classfileformat_versiondetails,
 				new String[] {
 					versionNumber,
 					Integer.toString(majorVersion),
 					Integer.toString(minorVersion),
 					((accessFlags & IModifierConstants.ACC_SUPER) != 0
-							? Util.bind("classfileformat.superflagisset")//$NON-NLS-1$
-							: Util.bind("classfileformat.superflagisnotset"))//$NON-NLS-1$
+							? Messages.classfileformat_superflagisset
+							: Messages.classfileformat_superflagisnotset)
 					+ (isDeprecated(classFileReader) ? ", deprecated" : EMPTY_OUTPUT)//$NON-NLS-1$
 				}));
 			writeNewLine(buffer, lineSeparator, 0);
 			if (signatureAttribute != null) {
-				buffer
-					.append(Util.bind("disassembler.begincommentline"))	 //$NON-NLS-1$
-					.append(Util.bind("disassembler.signatureattributeheader")) //$NON-NLS-1$
-					.append(signatureAttribute.getSignature());
+				buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature()))); 
 				writeNewLine(buffer, lineSeparator, 0);
 			}
 		}
@@ -746,7 +527,7 @@
 		IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
 		IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(classFileReader, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
 		
-		if (mode == DETAILED) {
+		if (checkMode(mode, DETAILED)) {
 			// disassemble compact version of annotations
 			if (runtimeInvisibleAnnotationsAttribute != null) {
 				disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, 1);
@@ -776,7 +557,7 @@
 			decodeModifiersForType(buffer, accessFlags);
 			if (isSynthetic(classFileReader)) {
 				buffer.append("synthetic"); //$NON-NLS-1$
-				buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+				buffer.append(Messages.disassembler_space); 
 			}
 		}
 		
@@ -808,19 +589,19 @@
 				CharOperation.replace(superinterface, '/', '.');
 				buffer
 					.append(superinterface)
-					.append(Util.bind("disassembler.comma"))//$NON-NLS-1$
-					.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+					.append(Messages.disassembler_comma)
+					.append(Messages.disassembler_space); 
 			}
 			char[] superinterface = superclassInterfaces[length - 1];
 			CharOperation.replace(superinterface, '/', '.');
 			buffer.append(superinterface);
 		}
-		buffer.append(Util.bind("disassembler.opentypedeclaration")); //$NON-NLS-1$
-		if (mode == SYSTEM) {
+		buffer.append(Messages.bind(Messages.disassembler_opentypedeclaration)); 
+		if (checkMode(mode, SYSTEM)) {
 			disassemble(classFileReader.getConstantPool(), buffer, lineSeparator, 1);
 		}
 		disassembleTypeMembers(classFileReader, buffer, lineSeparator, 1, mode);
-		if (mode == DETAILED || mode == SYSTEM) {
+		if (checkMode(mode, SYSTEM | DETAILED)) {
 			IClassFileAttribute[] attributes = classFileReader.getAttributes();
 			length = attributes.length;
 			IEnclosingMethodAttribute enclosingMethodAttribute = getEnclosingMethodAttribute(classFileReader);
@@ -846,7 +627,7 @@
 			if (enclosingMethodAttribute != null) {
 				disassemble(enclosingMethodAttribute, buffer, lineSeparator, 0);
 			}
-			if (mode == SYSTEM) {
+			if (checkMode(mode, SYSTEM)) {
 				if (runtimeVisibleAnnotationsAttribute != null) {
 					disassemble((IRuntimeVisibleAnnotationsAttribute) runtimeVisibleAnnotationsAttribute, buffer, lineSeparator, 0);
 				}
@@ -871,18 +652,18 @@
 			}
 		}
 		writeNewLine(buffer, lineSeparator, 0);
-		buffer.append(Util.bind("disassembler.closetypedeclaration")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_closetypedeclaration); 
 		return buffer.toString();
 	}
 	
-	private void disassemble(ICodeAttribute codeAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
+	private void disassemble(ICodeAttribute codeAttribute, StringBuffer buffer, String lineSeparator, int tabNumber, int mode) {
 		writeNewLine(buffer, lineSeparator, tabNumber - 1);
-		DefaultBytecodeVisitor visitor = new DefaultBytecodeVisitor(codeAttribute.getCodeLength(), buffer, lineSeparator, tabNumber);
+		DefaultBytecodeVisitor visitor = new DefaultBytecodeVisitor(codeAttribute, buffer, lineSeparator, tabNumber, mode);
 		try {
 			codeAttribute.traverse(visitor);
 		} catch(ClassFormatException e) {
 			dumpTab(tabNumber + 2, buffer);
-			buffer.append("Class format Exception");//$NON-NLS-1$
+			buffer.append(Messages.classformat_classformatexception);
 			writeNewLine(buffer, lineSeparator, tabNumber + 1);
 		}
 		int exceptionTableLength = codeAttribute.getExceptionTableLength();
@@ -890,43 +671,41 @@
 			final int tabNumberForExceptionAttribute = tabNumber + 2;
 			dumpTab(tabNumberForExceptionAttribute, buffer);
 			IExceptionTableEntry[] exceptionTableEntries = codeAttribute.getExceptionTable();
-			buffer.append(Util.bind("disassembler.exceptiontableheader")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_exceptiontableheader); 
 			writeNewLine(buffer, lineSeparator, tabNumberForExceptionAttribute + 1);
 			for (int i = 0; i < exceptionTableLength - 1; i++) {
 				IExceptionTableEntry exceptionTableEntry = exceptionTableEntries[i];
-				buffer
-					.append(Util.bind("classfileformat.exceptiontablefrom")) //$NON-NLS-1$
-					.append(exceptionTableEntry.getStartPC())
-					.append(Util.bind("classfileformat.exceptiontableto")) //$NON-NLS-1$
-					.append(exceptionTableEntry.getEndPC())
-					.append(Util.bind("classfileformat.exceptiontablegoto")) //$NON-NLS-1$
-					.append(exceptionTableEntry.getHandlerPC())
-					.append(Util.bind("classfileformat.exceptiontablewhen")); //$NON-NLS-1$
-				if (exceptionTableEntry.getCatchTypeIndex() == 0) {
-					buffer.append(ANY_EXCEPTION);
-				} else {
-					char[] catchType = exceptionTableEntry.getCatchType();
+				char[] catchType;
+				if (exceptionTableEntry.getCatchTypeIndex() != 0) {
+					catchType = exceptionTableEntry.getCatchType();
 					CharOperation.replace(catchType, '/', '.');
-					buffer.append(catchType);
+				} else {
+					catchType = ANY_EXCEPTION;
 				}
+				buffer.append(Messages.bind(Messages.classfileformat_exceptiontableentry,
+					new String[] {
+						Integer.toString(exceptionTableEntry.getStartPC()),
+						Integer.toString(exceptionTableEntry.getEndPC()),
+						Integer.toString(exceptionTableEntry.getHandlerPC()),
+						new String(catchType)
+					}));
 				writeNewLine(buffer, lineSeparator, tabNumberForExceptionAttribute + 1);
 			}
 			IExceptionTableEntry exceptionTableEntry = exceptionTableEntries[exceptionTableLength - 1];
-			buffer
-				.append(Util.bind("classfileformat.exceptiontablefrom")) //$NON-NLS-1$
-				.append(exceptionTableEntry.getStartPC())
-				.append(Util.bind("classfileformat.exceptiontableto")) //$NON-NLS-1$
-				.append(exceptionTableEntry.getEndPC())
-				.append(Util.bind("classfileformat.exceptiontablegoto")) //$NON-NLS-1$
-				.append(exceptionTableEntry.getHandlerPC())
-				.append(Util.bind("classfileformat.exceptiontablewhen")); //$NON-NLS-1$
-			if (exceptionTableEntry.getCatchTypeIndex() == 0) {
-				buffer.append(ANY_EXCEPTION);
-			} else {
-				char[] catchType = exceptionTableEntry.getCatchType();
+			char[] catchType;
+			if (exceptionTableEntry.getCatchTypeIndex() != 0) {
+				catchType = exceptionTableEntry.getCatchType();
 				CharOperation.replace(catchType, '/', '.');
-				buffer.append(catchType);
+			} else {
+				catchType = ANY_EXCEPTION;
 			}
+			buffer.append(Messages.bind(Messages.classfileformat_exceptiontableentry,
+				new String[] {
+					Integer.toString(exceptionTableEntry.getStartPC()),
+					Integer.toString(exceptionTableEntry.getEndPC()),
+					Integer.toString(exceptionTableEntry.getHandlerPC()),
+					new String(catchType)
+				}));
 			writeNewLine(buffer, lineSeparator, 0);
 		}
 		ILineNumberAttribute lineNumberAttribute = codeAttribute.getLineNumberAttribute();
@@ -934,31 +713,29 @@
 		if (lineAttributeLength != 0) {
 			int tabNumberForLineAttribute = tabNumber + 2;
 			dumpTab(tabNumberForLineAttribute, buffer);
-			buffer.append(Util.bind("disassembler.linenumberattributeheader")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_linenumberattributeheader); 
 			writeNewLine(buffer, lineSeparator, tabNumberForLineAttribute + 1);
 			int[][] lineattributesEntries = lineNumberAttribute.getLineNumberTable();
 			for (int i = 0; i < lineAttributeLength - 1; i++) {
-				buffer
-					.append(Util.bind("classfileformat.linenumbertablefrom")) //$NON-NLS-1$
-					.append(lineattributesEntries[i][0])
-					.append(Util.bind("classfileformat.linenumbertableto")) //$NON-NLS-1$
-					.append(lineattributesEntries[i][1])
-					.append(Util.bind("classfileformat.linenumbertableclose")); //$NON-NLS-1$
+				buffer.append(Messages.bind(Messages.classfileformat_linenumbertableentry,
+					new String[] {
+						Integer.toString(lineattributesEntries[i][0]),
+						Integer.toString(lineattributesEntries[i][1])
+					}));
 				writeNewLine(buffer, lineSeparator, tabNumberForLineAttribute + 1);
 			}
-			buffer
-				.append(Util.bind("classfileformat.linenumbertablefrom")) //$NON-NLS-1$
-				.append(lineattributesEntries[lineAttributeLength - 1][0])
-				.append(Util.bind("classfileformat.linenumbertableto")) //$NON-NLS-1$
-				.append(lineattributesEntries[lineAttributeLength - 1][1])
-				.append(Util.bind("classfileformat.linenumbertableclose")); //$NON-NLS-1$
+			buffer.append(Messages.bind(Messages.classfileformat_linenumbertableentry,
+				new String[] {
+					Integer.toString(lineattributesEntries[lineAttributeLength - 1][0]),
+					Integer.toString(lineattributesEntries[lineAttributeLength - 1][1])
+				}));
 		} 
 		ILocalVariableAttribute localVariableAttribute = codeAttribute.getLocalVariableAttribute();
 		int localVariableAttributeLength = localVariableAttribute == null ? 0 : localVariableAttribute.getLocalVariableTableLength();
 		if (localVariableAttributeLength != 0) {
 			int tabNumberForLocalVariableAttribute = tabNumber + 2;
 			writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute);
-			buffer.append(Util.bind("disassembler.localvariabletableattributeheader")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_localvariabletableattributeheader); 
 			writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
 			ILocalVariableTableEntry[] localVariableTableEntries = localVariableAttribute.getLocalVariableTable();
 			for (int i = 0; i < localVariableAttributeLength - 1; i++) {
@@ -966,41 +743,35 @@
 				int index= localVariableTableEntry.getIndex();
 				int startPC = localVariableTableEntry.getStartPC();
 				int length  = localVariableTableEntry.getLength();
-				buffer
-					.append(Util.bind("classfileformat.localvariabletablefrom")) //$NON-NLS-1$
-					.append(startPC)
-					.append(Util.bind("classfileformat.localvariabletableto")) //$NON-NLS-1$
-					.append(startPC + length)
-					.append(Util.bind("classfileformat.localvariabletablelocalname")) //$NON-NLS-1$
-					.append(localVariableTableEntry.getName())
-					.append(Util.bind("classfileformat.localvariabletablelocalindex")) //$NON-NLS-1$
-					.append(index)
-					.append(Util.bind("classfileformat.localvariabletablelocaltype")); //$NON-NLS-1$
-				buffer.append(localVariableTableEntry.getDescriptor());
+				buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
+					new String[] {
+						Integer.toString(startPC),
+						Integer.toString(startPC + length),
+						new String(localVariableTableEntry.getName()),
+						Integer.toString(index),
+						new String(localVariableTableEntry.getDescriptor())
+					}));
 				writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
 			}
 			ILocalVariableTableEntry localVariableTableEntry = localVariableTableEntries[localVariableAttributeLength - 1];
 			int index= localVariableTableEntry.getIndex();
 			int startPC = localVariableTableEntry.getStartPC();
 			int length  = localVariableTableEntry.getLength();
-			buffer
-				.append(Util.bind("classfileformat.localvariabletablefrom")) //$NON-NLS-1$
-				.append(startPC)
-				.append(Util.bind("classfileformat.localvariabletableto")) //$NON-NLS-1$
-				.append(startPC + length)
-				.append(Util.bind("classfileformat.localvariabletablelocalname")) //$NON-NLS-1$
-				.append(localVariableTableEntry.getName())
-				.append(Util.bind("classfileformat.localvariabletablelocalindex")) //$NON-NLS-1$
-				.append(index)
-				.append(Util.bind("classfileformat.localvariabletablelocaltype")); //$NON-NLS-1$
-			buffer.append(localVariableTableEntry.getDescriptor());
+			buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
+				new String[] {
+					Integer.toString(startPC),
+					Integer.toString(startPC + length),
+					new String(localVariableTableEntry.getName()),
+					Integer.toString(index),
+					new String(localVariableTableEntry.getDescriptor())
+				}));
 		} 
 		ILocalVariableTypeTableAttribute localVariableTypeAttribute= getLocalVariableTypeAttribute(codeAttribute);
 		int localVariableTypeTableLength = localVariableTypeAttribute == null ? 0 : localVariableTypeAttribute.getLocalVariableTypeTableLength();
 		if (localVariableTypeTableLength != 0) {
 			int tabNumberForLocalVariableAttribute = tabNumber + 2;
 			writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute);
-			buffer.append(Util.bind("disassembler.localvariabletypetableattributeheader")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_localvariabletypetableattributeheader); 
 			writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
 			ILocalVariableTypeTableEntry[] localVariableTypeTableEntries = localVariableTypeAttribute.getLocalVariableTypeTable();
 			for (int i = 0; i < localVariableTypeTableLength - 1; i++) {
@@ -1008,110 +779,107 @@
 				int index= localVariableTypeTableEntry.getIndex();
 				int startPC = localVariableTypeTableEntry.getStartPC();
 				int length  = localVariableTypeTableEntry.getLength();
-				buffer
-					.append(Util.bind("classfileformat.localvariabletablefrom")) //$NON-NLS-1$
-					.append(startPC)
-					.append(Util.bind("classfileformat.localvariabletableto")) //$NON-NLS-1$
-					.append(startPC + length)
-					.append(Util.bind("classfileformat.localvariabletablelocalname")) //$NON-NLS-1$
-					.append(localVariableTypeTableEntry.getName())
-					.append(Util.bind("classfileformat.localvariabletablelocalindex")) //$NON-NLS-1$
-					.append(index)
-					.append(Util.bind("classfileformat.localvariabletablelocaltype")); //$NON-NLS-1$
-				buffer.append(localVariableTypeTableEntry.getSignature());
+				buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
+					new String[] {
+						Integer.toString(startPC),
+						Integer.toString(startPC + length),
+						new String(localVariableTypeTableEntry.getName()),
+						Integer.toString(index),
+						new String(localVariableTypeTableEntry.getSignature())
+					}));
 				writeNewLine(buffer, lineSeparator, tabNumberForLocalVariableAttribute + 1);
 			}
 			ILocalVariableTypeTableEntry localVariableTypeTableEntry = localVariableTypeTableEntries[localVariableTypeTableLength - 1];
 			int index= localVariableTypeTableEntry.getIndex();
 			int startPC = localVariableTypeTableEntry.getStartPC();
 			int length  = localVariableTypeTableEntry.getLength();
-			buffer
-				.append(Util.bind("classfileformat.localvariabletablefrom")) //$NON-NLS-1$
-				.append(startPC)
-				.append(Util.bind("classfileformat.localvariabletableto")) //$NON-NLS-1$
-				.append(startPC + length)
-				.append(Util.bind("classfileformat.localvariabletablelocalname")) //$NON-NLS-1$
-				.append(localVariableTypeTableEntry.getName())
-				.append(Util.bind("classfileformat.localvariabletablelocalindex")) //$NON-NLS-1$
-				.append(index)
-				.append(Util.bind("classfileformat.localvariabletablelocaltype")) //$NON-NLS-1$
-				.append(localVariableTypeTableEntry.getSignature());
+			buffer.append(Messages.bind(Messages.classfileformat_localvariabletableentry,
+				new String[] {
+					Integer.toString(startPC),
+					Integer.toString(startPC + length),
+					new String(localVariableTypeTableEntry.getName()),
+					Integer.toString(index),
+					new String(localVariableTypeTableEntry.getSignature())
+				}));
 		} 
 	}
 
 	private void disassemble(IConstantPool constantPool, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber);
 		int length = constantPool.getConstantPoolCount();
-		buffer.append(Util.bind("disassembler.constantpoolheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_constantpoolheader); 
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
 		for (int i = 1; i < length; i++) {
 			IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(i);
 			switch (constantPool.getEntryKind(i)) {
 				case IConstantPoolConstant.CONSTANT_Class :
 					buffer.append(
-						Util.bind("disassembler.constantpool.class", //$NON-NLS-1$
-						new String[] {
-							Integer.toString(i),
-							Integer.toString(constantPoolEntry.getClassInfoNameIndex()),
-							new String(constantPoolEntry.getClassInfoName())})); //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_class,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(constantPoolEntry.getClassInfoNameIndex()),
+								new String(constantPoolEntry.getClassInfoName())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Double :
 					buffer.append(
-						Util.bind("disassembler.constantpool.double", //$NON-NLS-1$
-						new String[] {
-							Integer.toString(i),
-							Double.toString(constantPoolEntry.getDoubleValue())})); //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_double,
+							new String[] {
+								Integer.toString(i),
+								Double.toString(constantPoolEntry.getDoubleValue())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Fieldref :
 					buffer.append(
-						Util.bind("disassembler.constantpool.fieldref", //$NON-NLS-1$
-						new String[] {
+						Messages.bind(Messages.disassembler_constantpool_fieldref,
+							new String[] {
 							Integer.toString(i),
 							Integer.toString(constantPoolEntry.getClassIndex()),
 							Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
 							new String(constantPoolEntry.getClassName()),
-							getFieldRefNameAndType(constantPoolEntry)})); //$NON-NLS-1$
+							new String(constantPoolEntry.getFieldName()),
+							new String(constantPoolEntry.getFieldDescriptor())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Float :
 					buffer.append(
-						Util.bind("disassembler.constantpool.float", //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_float,
 						new String[] {
 							Integer.toString(i),
-							Float.toString(constantPoolEntry.getFloatValue())})); //$NON-NLS-1$
+							Float.toString(constantPoolEntry.getFloatValue())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Integer :
 					buffer.append(
-						Util.bind("disassembler.constantpool.integer", //$NON-NLS-1$
-						new String[] {
+						Messages.bind(Messages.disassembler_constantpool_integer,
+							new String[] {
 							Integer.toString(i),
-							Integer.toString(constantPoolEntry.getIntegerValue())})); //$NON-NLS-1$
+							Integer.toString(constantPoolEntry.getIntegerValue())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_InterfaceMethodref :
 					buffer.append(
-							Util.bind("disassembler.constantpool.interfacemethodref", //$NON-NLS-1$
-							new String[] {
-								Integer.toString(i),
-								Integer.toString(constantPoolEntry.getClassIndex()),
-								Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
-								new String(constantPoolEntry.getClassName()),
-								getMethodRefNameAndType(constantPoolEntry)})); //$NON-NLS-1$
+							Messages.bind(Messages.disassembler_constantpool_interfacemethodref,
+								new String[] {
+									Integer.toString(i),
+									Integer.toString(constantPoolEntry.getClassIndex()),
+									Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
+									new String(constantPoolEntry.getClassName()),
+									new String(constantPoolEntry.getMethodName()),
+									new String(constantPoolEntry.getMethodDescriptor())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Long :
 					buffer.append(
-						Util.bind("disassembler.constantpool.long", //$NON-NLS-1$
-						new String[] {
-							Integer.toString(i),
-							Long.toString(constantPoolEntry.getLongValue())})); //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_long,
+							new String[] {
+								Integer.toString(i),
+								Long.toString(constantPoolEntry.getLongValue())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Methodref :
 					buffer.append(
-							Util.bind("disassembler.constantpool.methodref", //$NON-NLS-1$
-							new String[] {
-								Integer.toString(i),
-								Integer.toString(constantPoolEntry.getClassIndex()),
-								Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
-								new String(constantPoolEntry.getClassName()),
-								getMethodRefNameAndType(constantPoolEntry)})); //$NON-NLS-1$
+							Messages.bind(Messages.disassembler_constantpool_methodref,
+								new String[] {
+									Integer.toString(i),
+									Integer.toString(constantPoolEntry.getClassIndex()),
+									Integer.toString(constantPoolEntry.getNameAndTypeIndex()),
+									new String(constantPoolEntry.getClassName()),
+									new String(constantPoolEntry.getMethodName()),
+									new String(constantPoolEntry.getMethodDescriptor())}));
 					break;
 				case IConstantPoolConstant.CONSTANT_NameAndType :
 					int nameIndex = constantPoolEntry.getNameAndTypeInfoNameIndex();
@@ -1121,28 +889,28 @@
 					entry = constantPool.decodeEntry(typeIndex);
 					char[] typeValue = entry.getUtf8Value();
 					buffer.append(
-						Util.bind("disassembler.constantpool.name_and_type", //$NON-NLS-1$
-						new String[] {
-							Integer.toString(i),
-							Integer.toString(nameIndex),
-							Integer.toString(typeIndex),
-							String.valueOf(nameValue),
-							String.valueOf(typeValue)})); //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_name_and_type,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(nameIndex),
+								Integer.toString(typeIndex),
+								String.valueOf(nameValue),
+								String.valueOf(typeValue)}));
 					break;
 				case IConstantPoolConstant.CONSTANT_String :
 					buffer.append(
-						Util.bind("disassembler.constantpool.string", //$NON-NLS-1$
-						new String[] {
-							Integer.toString(i),
-							Integer.toString(constantPoolEntry.getStringIndex()),
-							constantPoolEntry.getStringValue()})); //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_string,
+							new String[] {
+								Integer.toString(i),
+								Integer.toString(constantPoolEntry.getStringIndex()),
+								constantPoolEntry.getStringValue()}));
 					break;
 				case IConstantPoolConstant.CONSTANT_Utf8 :
 					buffer.append(
-						Util.bind("disassembler.constantpool.utf8", //$NON-NLS-1$
-						new String[] {
-							Integer.toString(i),
-							new String(constantPoolEntry.getUtf8Value())})); //$NON-NLS-1$
+						Messages.bind(Messages.disassembler_constantpool_utf8,
+							new String[] {
+								Integer.toString(i),
+								new String(constantPoolEntry.getUtf8Value())}));
 					break;
 			}
 			if (i < length - 1) {
@@ -1153,12 +921,12 @@
 
 	private void disassemble(IEnclosingMethodAttribute enclosingMethodAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.enclosingmethodheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_enclosingmethodheader); 
 		buffer
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+			.append(Messages.disassembler_constantpoolindex) 
 			.append(enclosingMethodAttribute.getEnclosingClassIndex())
 			.append(" ")//$NON-NLS-1$
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+			.append(Messages.disassembler_constantpoolindex) 
 			.append(enclosingMethodAttribute.getMethodNameAndTypeIndex())
 			.append(" ")//$NON-NLS-1$
 			.append(enclosingMethodAttribute.getEnclosingClass()); //$NON-NLS-1$
@@ -1178,29 +946,24 @@
 		char[] fieldDescriptor = fieldInfo.getDescriptor();
 		IClassFileAttribute classFileAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.SIGNATURE);
 		ISignatureAttribute signatureAttribute = (ISignatureAttribute) classFileAttribute;
-		if (mode == DETAILED || mode == SYSTEM) {
-			buffer
-				.append(Util.bind("disassembler.begincommentline")) //$NON-NLS-1$
-				.append(Util.bind("classfileformat.fieldddescriptor")) //$NON-NLS-1$
-				.append(Util.bind("classfileformat.fielddescriptorindex")) //$NON-NLS-1$
-				.append(fieldInfo.getDescriptorIndex())
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-				.append(fieldDescriptor);
+		if (checkMode(mode, SYSTEM | DETAILED)) {
+			buffer.append(Messages.bind(Messages.classfileformat_fieldddescriptor,
+				new String[] {
+					Integer.toString(fieldInfo.getDescriptorIndex()),
+					new String(fieldDescriptor)
+				}));
 			if (fieldInfo.isDeprecated()) {
-				buffer.append(Util.bind("disassembler.deprecated"));//$NON-NLS-1$
+				buffer.append(Messages.disassembler_deprecated);
 			}
 			writeNewLine(buffer, lineSeparator, tabNumber);
 			if (signatureAttribute != null) {
-				buffer
-					.append(Util.bind("disassembler.begincommentline"))	 //$NON-NLS-1$
-					.append(Util.bind("disassembler.signatureattributeheader")) //$NON-NLS-1$
-					.append(signatureAttribute.getSignature());
+				buffer.append(Messages.bind(Messages.disassembler_signatureattributeheader, new String(signatureAttribute.getSignature()))); 
 				writeNewLine(buffer, lineSeparator, tabNumber);
 			}
 		}
 		IClassFileAttribute runtimeVisibleAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS);
 		IClassFileAttribute runtimeInvisibleAnnotationsAttribute = Util.getAttribute(fieldInfo, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS);
-		if (mode == DETAILED) {
+		if (checkMode(mode, DETAILED)) {
 			// disassemble compact version of annotations
 			if (runtimeInvisibleAnnotationsAttribute != null) {
 				disassembleAsModifier((IRuntimeInvisibleAnnotationsAttribute) runtimeInvisibleAnnotationsAttribute, buffer, lineSeparator, tabNumber + 1);
@@ -1214,14 +977,14 @@
 		decodeModifiersForField(buffer, fieldInfo.getAccessFlags());
 		if (fieldInfo.isSynthetic()) {
 			buffer.append("synthetic"); //$NON-NLS-1$
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 		}
 		buffer.append(getSignatureForField(fieldDescriptor));
-		buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+		buffer.append(' ');
 		buffer.append(new String(fieldInfo.getName()));
 		IConstantValueAttribute constantValueAttribute = fieldInfo.getConstantValueAttribute();
 		if (constantValueAttribute != null) {
-			buffer.append(Util.bind("disassembler.fieldhasconstant")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_fieldhasconstant); 
 			IConstantPoolEntry constantPoolEntry = constantValueAttribute.getConstantValue();
 			switch(constantPoolEntry.getKind()) {
 				case IConstantPoolConstant.CONSTANT_Long :
@@ -1255,8 +1018,8 @@
 					buffer.append("\"" + decodeStringValue(constantPoolEntry.getStringValue()) + "\"" );//$NON-NLS-1$//$NON-NLS-2$
 			}
 		}
-		buffer.append(Util.bind("disassembler.endoffieldheader")); //$NON-NLS-1$
-		if (mode == SYSTEM) {
+		buffer.append(Messages.disassembler_endoffieldheader); 
+		if (checkMode(mode, SYSTEM)) {
 			IClassFileAttribute[] attributes = fieldInfo.getAttributes();
 			int length = attributes.length;
 			if (length != 0) {
@@ -1283,7 +1046,7 @@
 	
 	private void disassemble(IInnerClassesAttribute innerClassesAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber);
-		buffer.append(Util.bind("disassembler.innerattributesheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_innerattributesheader); 
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
 		IInnerClassesAttributeEntry[] innerClassesAttributeEntries = innerClassesAttribute.getInnerClassAttributesEntries();
 		int length = innerClassesAttributeEntries.length;
@@ -1296,48 +1059,48 @@
 			innerNameIndex = innerClassesAttributeEntry.getInnerNameIndex();
 			accessFlags = innerClassesAttributeEntry.getAccessFlags();
 			buffer
-				.append(Util.bind("disassembler.openinnerclassentry")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.inner_class_info_name")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+				.append(Messages.disassembler_openinnerclassentry) 
+				.append(Messages.disassembler_inner_class_info_name) 
+				.append(Messages.disassembler_constantpoolindex) 
 				.append(innerClassNameIndex);
 			if (innerClassNameIndex != 0) {
 				buffer
-					.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+					.append(Messages.disassembler_space) 
 					.append(innerClassesAttributeEntry.getInnerClassName());
 			}
 			buffer
-				.append(Util.bind("disassembler.comma")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.outer_class_info_name")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+				.append(Messages.disassembler_comma) 
+				.append(Messages.disassembler_space) 
+				.append(Messages.disassembler_outer_class_info_name) 
+				.append(Messages.disassembler_constantpoolindex) 
 				.append(outerClassNameIndex);
 			if (outerClassNameIndex != 0) {
 				buffer	
-					.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+					.append(Messages.disassembler_space) 
 					.append(innerClassesAttributeEntry.getOuterClassName());
 			}
 			writeNewLine(buffer, lineSeparator, tabNumber);
 			dumpTab(tabNumber, buffer);
-			buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_space); 
 			buffer
-				.append(Util.bind("disassembler.inner_name")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+				.append(Messages.disassembler_inner_name) 
+				.append(Messages.disassembler_constantpoolindex) 
 				.append(innerNameIndex);
 			if (innerNameIndex != 0) {
 				buffer
-					.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+					.append(Messages.disassembler_space) 
 					.append(innerClassesAttributeEntry.getInnerName());
 			}
 			buffer
-				.append(Util.bind("disassembler.comma")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.inner_accessflags")) //$NON-NLS-1$
+				.append(Messages.disassembler_comma) 
+				.append(Messages.disassembler_space) 
+				.append(Messages.disassembler_inner_accessflags) 
 				.append(accessFlags)
-				.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+				.append(Messages.disassembler_space); 
 			decodeModifiersForInnerClasses(buffer, accessFlags);
 			buffer
-				.append(Util.bind("disassembler.closeinnerclassentry")) //$NON-NLS-1$
-				.append(Util.bind("disassembler.comma")); //$NON-NLS-1$
+				.append(Messages.disassembler_closeinnerclassentry) 
+				.append(Messages.disassembler_comma); 
 			writeNewLine(buffer, lineSeparator, tabNumber + 1);
 		}
 		// last entry
@@ -1347,55 +1110,53 @@
 		innerNameIndex = innerClassesAttributeEntry.getInnerNameIndex();
 		accessFlags = innerClassesAttributeEntry.getAccessFlags();
 		buffer
-			.append(Util.bind("disassembler.openinnerclassentry")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.inner_class_info_name")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+			.append(Messages.disassembler_openinnerclassentry) 
+			.append(Messages.disassembler_inner_class_info_name) 
+			.append(Messages.disassembler_constantpoolindex) 
 			.append(innerClassNameIndex);
 		if (innerClassNameIndex != 0) {
 			buffer
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+				.append(Messages.disassembler_space) 
 				.append(innerClassesAttributeEntry.getInnerClassName());
 		}
 		buffer
-			.append(Util.bind("disassembler.comma")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.outer_class_info_name")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+			.append(Messages.disassembler_comma) 
+			.append(Messages.disassembler_space) 
+			.append(Messages.disassembler_outer_class_info_name) 
+			.append(Messages.disassembler_constantpoolindex) 
 			.append(outerClassNameIndex);
 		if (outerClassNameIndex != 0) {
 			buffer	
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+				.append(Messages.disassembler_space) 
 				.append(innerClassesAttributeEntry.getOuterClassName());
 		}
 		writeNewLine(buffer, lineSeparator, tabNumber);
 		dumpTab(tabNumber, buffer);
-		buffer.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_space); 
 		buffer
-			.append(Util.bind("disassembler.inner_name")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.constantpoolindex")) //$NON-NLS-1$
+			.append(Messages.disassembler_inner_name) 
+			.append(Messages.disassembler_constantpoolindex) 
 			.append(innerNameIndex);
 		if (innerNameIndex != 0) {
 			buffer
-				.append(Util.bind("disassembler.space")) //$NON-NLS-1$
+				.append(Messages.disassembler_space) 
 				.append(innerClassesAttributeEntry.getInnerName());
 		}
 		buffer
-			.append(Util.bind("disassembler.comma")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.space")) //$NON-NLS-1$
-			.append(Util.bind("disassembler.inner_accessflags")) //$NON-NLS-1$
+			.append(Messages.disassembler_comma) 
+			.append(Messages.disassembler_space) 
+			.append(Messages.disassembler_inner_accessflags) 
 			.append(accessFlags)
-			.append(Util.bind("disassembler.space")); //$NON-NLS-1$
+			.append(Messages.disassembler_space); 
 		decodeModifiersForInnerClasses(buffer, accessFlags);
-		buffer.append(Util.bind("disassembler.closeinnerclassentry")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_closeinnerclassentry); 
 	}
 
 	private void disassemble(int index, IParameterAnnotation parameterAnnotation, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		IAnnotation[] annotations = parameterAnnotation.getAnnotations();
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
 		buffer.append(
-			Util.bind("disassembler.parameterannotationentrystart", //$NON-NLS-1$
-			Integer.toString(index),
-			Integer.toString(annotations.length)));
+			Messages.bind(Messages.disassembler_parameterannotationentrystart, new String[] {Integer.toString(index), Integer.toString(annotations.length)}));
 		for (int i = 0, max = annotations.length; i < max; i++) {
 			disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1);
 		}
@@ -1403,7 +1164,7 @@
 
 	private void disassemble(IRuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.runtimeinvisibleannotationsattributeheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_runtimeinvisibleannotationsattributeheader); 
 		IAnnotation[] annotations = runtimeInvisibleAnnotationsAttribute.getAnnotations();
 		for (int i = 0, max = annotations.length; i < max; i++) {
 			disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1);
@@ -1412,7 +1173,7 @@
 
 	private void disassemble(IRuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.runtimeinvisibleparameterannotationsattributeheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_runtimeinvisibleparameterannotationsattributeheader); 
 		IParameterAnnotation[] parameterAnnotations = runtimeInvisibleParameterAnnotationsAttribute.getParameterAnnotations();
 		for (int i = 0, max = parameterAnnotations.length; i < max; i++) {
 			disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1);
@@ -1421,7 +1182,7 @@
 	
 	private void disassemble(IRuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.runtimevisibleannotationsattributeheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_runtimevisibleannotationsattributeheader); 
 		IAnnotation[] annotations = runtimeVisibleAnnotationsAttribute.getAnnotations();
 		for (int i = 0, max = annotations.length; i < max; i++) {
 			disassemble(annotations[i], buffer, lineSeparator, tabNumber + 1);
@@ -1430,7 +1191,7 @@
 
 	private void disassemble(IRuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute, StringBuffer buffer, String lineSeparator, int tabNumber) {
 		writeNewLine(buffer, lineSeparator, tabNumber + 1);
-		buffer.append(Util.bind("disassembler.runtimevisibleparameterannotationsattributeheader")); //$NON-NLS-1$
+		buffer.append(Messages.disassembler_runtimevisibleparameterannotationsattributeheader); 
 		IParameterAnnotation[] parameterAnnotations = runtimeVisibleParameterAnnotationsAttribute.getParameterAnnotations();
 		for (int i = 0, max = parameterAnnotations.length; i < max; i++) {
 			disassemble(i, parameterAnnotations[i], buffer, lineSeparator, tabNumber + 1);
@@ -1563,7 +1324,7 @@
 	
 	private final void dumpTab(int tabNumber, StringBuffer buffer) {
 		for (int i = 0; i < tabNumber; i++) {
-			buffer.append(Util.bind("disassembler.indentation")); //$NON-NLS-1$
+			buffer.append(Messages.disassembler_indentation); 
 		}
 	} 
 	
@@ -1571,7 +1332,7 @@
 	 * @see org.eclipse.jdt.core.util.ClassFileBytesDisassembler#getDescription()
 	 */
 	public String getDescription() {
-		return Util.bind("disassembler.description"); //$NON-NLS-1$
+		return Messages.disassembler_description; 
 	}
 
 	private IEnclosingMethodAttribute getEnclosingMethodAttribute(IClassFileReader classFileReader) {
@@ -1601,14 +1362,6 @@
 			}
 			return null;
 	}
-	private String getFieldRefNameAndType(IConstantPoolEntry entry) {
-		StringBuffer stringBuffer = new StringBuffer();
-		stringBuffer
-			.append(entry.getFieldName())
-			.append(' ')
-			.append(entry.getFieldDescriptor());
-		return String.valueOf(stringBuffer);
-	}
 	private ILocalVariableTypeTableAttribute getLocalVariableTypeAttribute(ICodeAttribute codeAttribute) {
 		IClassFileAttribute[] attributes = codeAttribute.getAttributes();
 		for (int i = 0, max = attributes.length; i < max; i++) {
@@ -1618,15 +1371,6 @@
 		}
 		return null;
 	}
-
-	private String getMethodRefNameAndType(IConstantPoolEntry entry) {
-		StringBuffer stringBuffer = new StringBuffer();
-		stringBuffer
-			.append(entry.getMethodName())
-			.append(' ')
-			.append(entry.getMethodDescriptor());
-		return String.valueOf(stringBuffer);
-	}
 	
 	private char[][] getParameterNames(char[] methodDescriptor, ICodeAttribute codeAttribute, int accessFlags) {
 		int paramCount = Signature.getParameterCount(methodDescriptor);
@@ -1642,17 +1386,17 @@
 					if (searchedEntry != null) {
 						parameterNames[i] = searchedEntry.getName();
 					} else {
-						parameterNames[i] = Util.bind("disassembler.parametername").toCharArray(); //$NON-NLS-1$
+						parameterNames[i] = Messages.disassembler_parametername.toCharArray(); 
 					}
 				}
 			} else {
 				for (int i = 0; i < paramCount; i++) {
-					parameterNames[i] = Util.bind("disassembler.parametername").toCharArray(); //$NON-NLS-1$
+					parameterNames[i] = Messages.disassembler_parametername.toCharArray(); 
 				}
 			}
 		} else {
 			for (int i = 0; i < paramCount; i++) {
-				parameterNames[i] = Util.bind("disassembler.parametername").toCharArray(); //$NON-NLS-1$
+				parameterNames[i] = Messages.disassembler_parametername.toCharArray(); 
 			}
 		}
 		return parameterNames;
@@ -1690,8 +1434,12 @@
 		return false;
 	}
 	
+	private boolean checkMode(int mode, int flag) {
+		return (mode & flag) != 0;
+	}
+	
 	private void writeNewLine(StringBuffer buffer, String lineSeparator, int tabNumber) {
 		buffer.append(lineSeparator);
 		dumpTab(tabNumber, buffer);
 	}
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java
index 5f701bd..83a5f40 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java
index 451e398..d0a6ff2 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java
index 844de07..37d4abc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionTableEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java
index 7a38b69..3ab3e51 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
index 813b9dc..522f6c3 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java
index fa4b732..79b712f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HashtableOfArrayToObject.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java
index d63bd65..3a968bf 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ICacheEnumeration.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java
index 8df7805..e282405 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ILRUCacheable.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java
index 1b891e9..3bb2b75 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java
index c44e9b2..80b18c5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttributeEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
new file mode 100644
index 0000000..a145a5a
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyKind.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+public class KeyKind extends BindingKeyParser {
+
+	public static final int F_TYPE = 0x0001;
+	public static final int F_METHOD = 0x0010;
+	public static final int F_FIELD = 0x0011;
+	public static final int F_TYPE_PARAMETER = 0x0100;
+	public static final int F_LOCAL_VAR = 0x0101;
+	public static final int F_MEMBER = 0x0110;
+	public static final int F_LOCAL = 0x0111;
+	public static final int F_PARAMETERIZED_TYPE = 0x1000;
+	public static final int F_RAW_TYPE = 0x1001;
+	public static final int F_WILDCARD_TYPE = 0x1010;
+	public static final int F_PARAMETERIZED_METHOD = 0x1011;
+	public static final int F_CAPTURE = 0x1111;
+	
+	public int flags = 0;
+	
+	public KeyKind(BindingKeyParser parser) {
+		super(parser);
+	}
+	
+	public KeyKind(String key) {
+		super(key);
+	}
+
+	public void consumeCapture() {
+		this.flags |= F_CAPTURE;
+	}
+	
+	public void consumeField(char[] fieldName) {
+		this.flags |= F_FIELD;
+	}
+
+	public void consumeLocalType(char[] uniqueKey) {
+		this.flags |= F_LOCAL;
+	}
+
+	public void consumeLocalVar(char[] varName) {
+		this.flags |= F_LOCAL_VAR;
+	}
+
+	public void consumeMemberType(char[] simpleTypeName) {
+		this.flags |= F_MEMBER;
+	}
+
+	public void consumeMethod(char[] selector, char[] signature) {
+		this.flags |= F_METHOD;
+	}
+
+	public void consumeParameterizedMethod() {
+		this.flags |= F_PARAMETERIZED_METHOD;
+	}
+
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		this.flags |= isRaw ? F_RAW_TYPE : F_PARAMETERIZED_TYPE;
+	}
+
+	public void consumeRawType() {
+		this.flags |= F_RAW_TYPE;
+	}
+
+	public void consumeTopLevelType() {
+		this.flags |= F_TYPE;
+	}
+
+	public void consumeTypeParameter(char[] typeParameterName) {
+		this.flags |= F_TYPE_PARAMETER;
+	}
+
+	public void consumeWildCard(int kind) {
+		this.flags |= F_WILDCARD_TYPE;
+	}
+
+	public BindingKeyParser newParser() {
+		return new BindingKeyParser(this);
+	}
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
new file mode 100644
index 0000000..c269c33
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/KeyToSignature.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
+
+/*
+ * Converts a binding key into a signature 
+ */
+// TODO (jerome) handle methods and fields
+public class KeyToSignature extends BindingKeyParser {
+	
+	public static final int SIGNATURE = 0;
+	public static final int TYPE_ARGUMENTS = 1;
+	public static final int DECLARING_TYPE = 2;
+	
+	public StringBuffer signature = new StringBuffer();
+	private int kind;
+	private ArrayList arguments = new ArrayList();
+	private ArrayList typeParameters = new ArrayList();
+	private int mainTypeStart = -1;
+	private int mainTypeEnd;
+	
+	public KeyToSignature(BindingKeyParser parser) {
+		super(parser);
+	}
+	
+	public KeyToSignature(String key, int kind) {
+		super(key);
+		this.kind = kind;
+	}
+	
+	public void consumeArrayDimension(char[] brakets) {
+		this.signature.append(brakets);
+	}
+	
+	public void consumeCapture() {
+		this.signature.append('!');
+	}
+		
+	public void consumeLocalType(char[] uniqueKey) {
+		this.signature = new StringBuffer();
+		// remove trailing semi-colon as it is added later in comsumeType()
+		uniqueKey = CharOperation.subarray(uniqueKey, 0, uniqueKey.length-1);
+		CharOperation.replace(uniqueKey, '/', '.');
+		this.signature.append(uniqueKey);
+	}
+	
+	public void consumeMethod(char[] selector, char[] methodSignature) {
+		this.arguments = new ArrayList();
+		if (this.kind == SIGNATURE) {
+			this.signature = new StringBuffer();
+			CharOperation.replace(methodSignature, '/', '.');
+			this.signature.append(methodSignature);
+		}
+	}
+	
+	public void consumeMemberType(char[] simpleTypeName) {
+		this.signature.append('$');
+		this.signature.append(simpleTypeName);
+	}
+
+	public void consumePackage(char[] pkgName) {
+		this.signature.append(pkgName);
+	}
+	
+	public void consumeParameterizedType(char[] simpleTypeName, boolean isRaw) {
+		if (simpleTypeName != null) {
+			// member type
+			this.signature.append('.');
+			this.signature.append(simpleTypeName);
+		}
+		if (!isRaw) {
+			this.signature.append('<');
+			int length = this.arguments.size();
+			for (int i = 0; i < length; i++) {
+				this.signature.append(this.arguments.get(i));
+			}
+			this.signature.append('>');
+			if (this.kind != TYPE_ARGUMENTS)
+				this.arguments = new ArrayList();
+		}
+	}
+	
+	public void consumeParser(BindingKeyParser parser) {
+		this.arguments.add(((KeyToSignature) parser).signature);
+	}
+	
+	public void consumeFullyQualifiedName(char[] fullyQualifiedName) {
+		this.signature.append('L');
+		this.signature.append(CharOperation.replaceOnCopy(fullyQualifiedName, '/', '.'));
+	}
+	
+	public void consumeSecondaryType(char[] simpleTypeName) {
+		this.signature.append('~');
+		this.mainTypeStart = this.signature.lastIndexOf(".") + 1; //$NON-NLS-1$
+		if (this.mainTypeStart == 0)
+			this.mainTypeStart = 1; // default package
+		this.mainTypeEnd = this.signature.length();
+		this.signature.append(simpleTypeName);
+	}
+
+	public void consumeType() {
+		int length = this.typeParameters.size();
+		if (length > 0) {
+			this.signature.append('<');
+			for (int i = 0; i < length; i++) {
+				this.signature.append('T');
+				this.signature.append((char[]) this.typeParameters.get(i));
+				this.signature.append(';');
+			}
+			this.signature.append('>');
+			this.typeParameters = new ArrayList();
+		}
+		// remove main type if needed
+		if (this.mainTypeStart != -1) {
+			this.signature.replace(this.mainTypeStart, this.mainTypeEnd, ""); //$NON-NLS-1$
+		}
+		this.signature.append(';');
+	}
+	
+	public void consumeTypeParameter(char[] typeParameterName) {
+		this.typeParameters.add(typeParameterName);
+	}
+	
+	public void consumeTypeVariable(char[] typeVariableName) {
+		this.signature = new StringBuffer();
+		this.signature.append('T');
+		this.signature.append(typeVariableName);
+		this.signature.append(';');
+	}
+	
+	public void consumeWildCard(int wildCardKind) {
+		switch (wildCardKind) {
+			case Wildcard.UNBOUND:
+				this.signature.append('*');
+				break;
+			case Wildcard.EXTENDS:
+				this.signature.append('+');
+				break;
+			case Wildcard.SUPER:
+				this.signature.append('-');
+				break;
+			default:
+				// malformed
+				return;
+		}
+	}
+	
+	public String[] getTypeArguments() {
+		int length = this.arguments.size();
+		String[] result = new String[length];
+		for (int i = 0; i < length; i++) {
+			result[i] = ((StringBuffer) this.arguments.get(i)).toString();
+		}
+		return result;
+	}
+	
+	public BindingKeyParser newParser() {
+		return new KeyToSignature(this);
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return this.signature.toString();
+	}
+
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java
index 1f93358..405afa5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LRUCache.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java
index 19a94f0..edfe140 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java
index d82413c..00fe845 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java
index 0784822..1f2a8f4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTableEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java
index e776134..91e87dc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java
index a2390c3..e3eb83d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
index bac7c0c..7d7c76f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MementoTokenizer.java
@@ -1,16 +1,15 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.util;
 
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.core.JavaElement;
 
 public class MementoTokenizer {
@@ -84,7 +83,7 @@
 			switch (this.memento[this.index]) {
 				case JavaElement.JEM_ESCAPE:
 					if (buffer == null) buffer = new StringBuffer();
-					buffer.append(CharOperation.subarray(this.memento, start, this.index));
+					buffer.append(this.memento, start, this.index - start);
 					start = ++this.index;
 					break;
 				case JavaElement.JEM_COUNT:
@@ -106,10 +105,10 @@
 			this.index++;
 		}
 		if (buffer != null) {
-			buffer.append(CharOperation.subarray(this.memento, start, this.index));
+			buffer.append(this.memento, start, this.index - start);
 			return buffer.toString();
 		} else {
-			return new String(CharOperation.subarray(this.memento, start, this.index));
+			return new String(this.memento, start, this.index - start);
 		}
 	}
 	
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
new file mode 100644
index 0000000..3678ae1
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Messages.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.util;
+
+import java.text.MessageFormat;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class Messages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.core.util.messages";//$NON-NLS-1$
+
+	private Messages() {
+		// Do not instantiate
+	}
+
+	public static String hierarchy_nullProject;
+	public static String hierarchy_nullRegion;
+	public static String hierarchy_nullFocusType;
+	public static String hierarchy_creating;
+	public static String hierarchy_creatingOnType;
+	public static String element_doesNotExist;
+	public static String element_notOnClasspath;
+	public static String element_invalidClassFileName;
+	public static String element_reconciling;
+	public static String element_attachingSource;
+	public static String element_invalidResourceForProject;
+	public static String element_nullName;
+	public static String element_nullType;
+	public static String element_illegalParent;
+	public static String sourcetype_invalidName;
+	public static String operation_needElements;
+	public static String operation_needName;
+	public static String operation_needPath;
+	public static String operation_needAbsolutePath;
+	public static String operation_needString;
+	public static String operation_notSupported;
+	public static String operation_cancelled;
+	public static String operation_nullContainer;
+	public static String operation_nullName;
+	public static String operation_copyElementProgress;
+	public static String operation_moveElementProgress;
+	public static String operation_renameElementProgress;
+	public static String operation_copyResourceProgress;
+	public static String operation_moveResourceProgress;
+	public static String operation_renameResourceProgress;
+	public static String operation_createUnitProgress;
+	public static String operation_createFieldProgress;
+	public static String operation_createImportsProgress;
+	public static String operation_createInitializerProgress;
+	public static String operation_createMethodProgress;
+	public static String operation_createPackageProgress;
+	public static String operation_createPackageFragmentProgress;
+	public static String operation_createTypeProgress;
+	public static String operation_deleteElementProgress;
+	public static String operation_deleteResourceProgress;
+	public static String operation_cannotRenameDefaultPackage;
+	public static String operation_pathOutsideProject;
+	public static String operation_sortelements;
+	public static String workingCopy_commit;
+	public static String build_preparingBuild;
+	public static String build_readStateProgress;
+	public static String build_saveStateProgress;
+	public static String build_saveStateComplete;
+	public static String build_readingDelta;
+	public static String build_analyzingDeltas;
+	public static String build_analyzingSources;
+	public static String build_cleaningOutput;
+	public static String build_copyingResources;
+	public static String build_compiling;
+	public static String build_foundHeader;
+	public static String build_fixedHeader;
+	public static String build_oneError;
+	public static String build_oneWarning;
+	public static String build_multipleErrors;
+	public static String build_multipleWarnings;
+	public static String build_done;
+	public static String build_wrongFileFormat;
+	public static String build_cannotSaveState;
+	public static String build_cannotSaveStates;
+	public static String build_initializationError;
+	public static String build_serializationError;
+	public static String build_classFileCollision;
+	public static String build_duplicateClassFile;
+	public static String build_duplicateResource;
+	public static String build_inconsistentClassFile;
+	public static String build_inconsistentProject;
+	public static String build_incompleteClassPath;
+	public static String build_missingSourceFile;
+	public static String build_prereqProjectHasClasspathProblems;
+	public static String build_prereqProjectMustBeRebuilt;
+	public static String build_abortDueToClasspathProblems;
+	public static String status_cannotUseDeviceOnPath;
+	public static String status_coreException;
+	public static String status_defaultPackageReadOnly;
+	public static String status_evaluationError;
+	public static String status_JDOMError;
+	public static String status_IOException;
+	public static String status_indexOutOfBounds;
+	public static String status_invalidContents;
+	public static String status_invalidDestination;
+	public static String status_invalidName;
+	public static String status_invalidPackage;
+	public static String status_invalidPath;
+	public static String status_invalidProject;
+	public static String status_invalidResource;
+	public static String status_invalidResourceType;
+	public static String status_invalidSibling;
+	public static String status_nameCollision;
+	public static String status_noLocalContents;
+	public static String status_OK;
+	public static String status_readOnly;
+	public static String status_targetException;
+	public static String status_updateConflict;
+	public static String classpath_buildPath;
+	public static String classpath_cannotNestEntryInEntry;
+	public static String classpath_cannotNestEntryInLibrary;
+	public static String classpath_cannotNestEntryInOutput;
+	public static String classpath_cannotNestOutputInEntry;
+	public static String classpath_cannotNestOutputInOutput;
+	public static String classpath_cannotReadClasspathFile;
+	public static String classpath_cannotReferToItself;
+	public static String classpath_cannotUseDistinctSourceFolderAsOutput;
+	public static String classpath_cannotUseLibraryAsOutput;
+	public static String classpath_closedProject;
+	public static String classpath_couldNotWriteClasspathFile;
+	public static String classpath_cycle;
+	public static String classpath_duplicateEntryPath;
+	public static String classpath_illegalContainerPath;
+	public static String classpath_illegalEntryInClasspathFile;
+	public static String classpath_illegalLibraryPath;
+	public static String classpath_illegalLibraryArchive;
+	public static String classpath_illegalExternalFolder;
+	public static String classpath_illegalProjectPath;
+	public static String classpath_illegalSourceFolderPath;
+	public static String classpath_illegalVariablePath;
+	public static String classpath_invalidClasspathInClasspathFile;
+	public static String classpath_invalidContainer;
+	public static String classpath_mustEndWithSlash;
+	public static String classpath_unboundContainerPath;
+	public static String classpath_unboundLibrary;
+	public static String classpath_unboundProject;
+	public static String classpath_settingOutputLocationProgress;
+	public static String classpath_settingProgress;
+	public static String classpath_unboundSourceAttachment;
+	public static String classpath_unboundSourceFolder;
+	public static String classpath_unboundVariablePath;
+	public static String classpath_unknownKind;
+	public static String classpath_xmlFormatError;
+	public static String classpath_disabledInclusionExclusionPatterns;
+	public static String classpath_disabledMultipleOutputLocations;
+	public static String classpath_incompatibleLibraryJDKLevel;
+	public static String file_notFound;
+	public static String file_badFormat;
+	public static String path_nullPath;
+	public static String path_mustBeAbsolute;
+	public static String cache_invalidLoadFactor;
+	public static String savedState_jobName;
+	public static String restrictedAccess_project;
+	public static String restrictedAccess_library;
+	public static String convention_unit_nullName;
+	public static String convention_unit_notJavaName;
+	public static String convention_classFile_nullName;
+	public static String convention_classFile_notClassFileName;
+	public static String convention_illegalIdentifier;
+	public static String convention_import_nullImport;
+	public static String convention_import_unqualifiedImport;
+	public static String convention_type_nullName;
+	public static String convention_type_nameWithBlanks;
+	public static String convention_type_dollarName;
+	public static String convention_type_lowercaseName;
+	public static String convention_type_invalidName;
+	public static String convention_package_nullName;
+	public static String convention_package_emptyName;
+	public static String convention_package_dotName;
+	public static String convention_package_nameWithBlanks;
+	public static String convention_package_consecutiveDotsName;
+	public static String convention_package_uppercaseName;
+	public static String dom_cannotDetail;
+	public static String dom_nullTypeParameter;
+	public static String dom_nullNameParameter;
+	public static String dom_nullReturnType;
+	public static String dom_nullExceptionType;
+	public static String dom_mismatchArgNamesAndTypes;
+	public static String dom_addNullChild;
+	public static String dom_addIncompatibleChild;
+	public static String dom_addChildWithParent;
+	public static String dom_unableAddChild;
+	public static String dom_addAncestorAsChild;
+	public static String dom_addNullSibling;
+	public static String dom_addSiblingBeforeRoot;
+	public static String dom_addIncompatibleSibling;
+	public static String dom_addSiblingWithParent;
+	public static String dom_addAncestorAsSibling;
+	public static String dom_addNullInterface;
+	public static String dom_nullInterfaces;
+	public static String correction_nullRequestor;
+	public static String correction_nullUnit;
+	public static String engine_searching;
+	public static String engine_searching_indexing;
+	public static String engine_searching_matching;
+	public static String exception_wrongFormat;
+	public static String process_name;
+	public static String manager_filesToIndex;
+	public static String manager_indexingInProgress;
+	public static String disassembler_description;
+	public static String disassembler_opentypedeclaration;
+	public static String disassembler_closetypedeclaration;
+	public static String disassembler_parametername;
+	public static String disassembler_localvariablename;
+	public static String disassembler_endofmethodheader;
+	public static String disassembler_begincommentline;
+	public static String disassembler_fieldhasconstant;
+	public static String disassembler_endoffieldheader;
+	public static String disassembler_sourceattributeheader;
+	public static String disassembler_enclosingmethodheader;
+	public static String disassembler_exceptiontableheader;
+	public static String disassembler_linenumberattributeheader;
+	public static String disassembler_localvariabletableattributeheader;
+	public static String disassembler_localvariabletypetableattributeheader;
+	public static String disassembler_arraydimensions;
+	public static String disassembler_innerattributesheader;
+	public static String disassembler_inner_class_info_name;
+	public static String disassembler_outer_class_info_name;
+	public static String disassembler_inner_name;
+	public static String disassembler_inner_accessflags;
+	public static String disassembler_genericattributeheader;
+	public static String disassembler_signatureattributeheader;
+	public static String disassembler_indentation;
+	public static String disassembler_constantpoolindex;
+	public static String disassembler_space;
+	public static String disassembler_comma;
+	public static String disassembler_openinnerclassentry;
+	public static String disassembler_closeinnerclassentry;
+	public static String disassembler_deprecated;
+	public static String disassembler_constantpoolheader;
+	public static String disassembler_constantpool_class;
+	public static String disassembler_constantpool_double;
+	public static String disassembler_constantpool_float;
+	public static String disassembler_constantpool_integer;
+	public static String disassembler_constantpool_long;
+	public static String disassembler_constantpool_string;
+	public static String disassembler_constantpool_fieldref;
+	public static String disassembler_constantpool_interfacemethodref;
+	public static String disassembler_constantpool_methodref;
+	public static String disassembler_constantpool_name_and_type;
+	public static String disassembler_constantpool_utf8;
+	public static String disassembler_annotationdefaultheader;
+	public static String disassembler_annotationdefaultvalue;
+	public static String disassembler_annotationenumvalue;
+	public static String disassembler_annotationclassvalue;
+	public static String disassembler_annotationannotationvalue;
+	public static String disassembler_annotationarrayvaluestart;
+	public static String disassembler_annotationarrayvalueend;
+	public static String disassembler_annotationentrystart;
+	public static String disassembler_annotationentryend;
+	public static String disassembler_annotationcomponent;
+	public static String disassembler_runtimevisibleannotationsattributeheader;
+	public static String disassembler_runtimeinvisibleannotationsattributeheader;
+	public static String disassembler_runtimevisibleparameterannotationsattributeheader;
+	public static String disassembler_runtimeinvisibleparameterannotationsattributeheader;
+	public static String disassembler_parameterannotationentrystart;
+	public static String classfileformat_versiondetails;
+	public static String classfileformat_methoddescriptor;
+	public static String classfileformat_fieldddescriptor;
+	public static String classfileformat_stacksAndLocals;
+	public static String classfileformat_superflagisnotset;
+	public static String classfileformat_superflagisset;
+	public static String classfileformat_clinitname;
+	public static String classformat_classformatexception;
+	public static String classformat_anewarray;
+	public static String classformat_checkcast;
+	public static String classformat_instanceof;
+	public static String classformat_ldc_w_class;
+	public static String classformat_ldc_w_float;
+	public static String classformat_ldc_w_integer;
+	public static String classformat_ldc_w_string;
+	public static String classformat_ldc2_w_long;
+	public static String classformat_ldc2_w_double;
+	public static String classformat_multianewarray;
+	public static String classformat_new;
+	public static String classformat_iinc;
+	public static String classformat_invokespecial;
+	public static String classformat_invokespecial_compact;
+	public static String classformat_invokeinterface;
+	public static String classformat_invokeinterface_compact;
+	public static String classformat_invokestatic;
+	public static String classformat_invokestatic_compact;
+	public static String classformat_invokevirtual;
+	public static String classformat_invokevirtual_compact;
+	public static String classformat_getfield;
+	public static String classformat_getstatic;
+	public static String classformat_putstatic;
+	public static String classformat_putfield;
+	public static String classformat_newarray_boolean;
+	public static String classformat_newarray_char;
+	public static String classformat_newarray_float;
+	public static String classformat_newarray_double;
+	public static String classformat_newarray_byte;
+	public static String classformat_newarray_short;
+	public static String classformat_newarray_int;
+	public static String classformat_newarray_long;
+	public static String classformat_store;
+	public static String classformat_load;
+	public static String classfileformat_anyexceptionhandler;
+	public static String classfileformat_exceptiontableentry;
+	public static String classfileformat_linenumbertableentry;
+	public static String classfileformat_localvariabletableentry;
+
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+	}
+	
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @return the manipulated String
+	 */
+	public static String bind(String message) {
+		return bind(message, null);
+	}
+	
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @param binding the object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding) {
+		return bind(message, new Object[] {binding});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @param binding1 An object to be inserted into the message
+	 * @param binding2 A second object to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object binding1, Object binding2) {
+		return bind(message, new Object[] {binding1, binding2});
+	}
+
+	/**
+	 * Bind the given message's substitution locations with the given string values.
+	 * 
+	 * @param message the message to be manipulated
+	 * @param bindings An array of objects to be inserted into the message
+	 * @return the manipulated String
+	 */
+	public static String bind(String message, Object[] bindings) {
+		return MessageFormat.format(message, bindings);
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java
index 283f7ab..9cae81d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
index c79ac6f..a0d634e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
index 389bce5..dbd2607 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,9 +21,12 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.parser.NLSLine;
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
 
 public class PublicScanner implements IScanner, ITerminalSymbols {
-
+	
+	//public int newIdentCount = 0;
+	
 	/* APIs ares
 	 - getNextToken() which return the current type of the token
 	   (this value is not memorized by the scanner)
@@ -33,6 +36,8 @@
 	 - currentPosition-1 gives the sourceEnd position into the stream 
 	*/
 	protected long sourceLevel;
+	protected long complianceLevel;
+
 	// 1.4 feature 
 	public boolean useAssertAsAnIndentifier = false;
 	//flag indicating if processed source contains occurrences of keyword assert 
@@ -63,8 +68,10 @@
 	public boolean scanningFloatLiteral = false;
 
 	//support for /** comments
-	public int[] commentStops = new int[10];
-	public int[] commentStarts = new int[10];
+	public static int COMMENT_ARRAYS_SIZE = 30;
+	public int[] commentStops = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentStarts = new int[COMMENT_ARRAYS_SIZE];
+	public int[] commentTagStarts = new int[COMMENT_ARRAYS_SIZE];
 	public int commentPtr = -1; // no comment test with commentPtr value -1
 	protected int lastCommentLinePosition = -1;
 	
@@ -96,12 +103,15 @@
 	public static final String INVALID_INPUT = "Invalid_Input"; //$NON-NLS-1$
 	public static final String INVALID_UNICODE_ESCAPE = "Invalid_Unicode_Escape"; //$NON-NLS-1$
 	public static final String INVALID_FLOAT = "Invalid_Float_Literal"; //$NON-NLS-1$
+	public static final String INVALID_LOW_SURROGATE = "Invalid_Low_Surrogate"; //$NON-NLS-1$
+	public static final String INVALID_HIGH_SURROGATE = "Invalid_High_Surrogate"; //$NON-NLS-1$
 
 	public static final String NULL_SOURCE_STRING = "Null_Source_String"; //$NON-NLS-1$
 	public static final String UNTERMINATED_STRING = "Unterminated_String"; //$NON-NLS-1$
 	public static final String UNTERMINATED_COMMENT = "Unterminated_Comment"; //$NON-NLS-1$
 	public static final String INVALID_CHAR_IN_STRING = "Invalid_Char_In_String"; //$NON-NLS-1$
-	public static final String INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$	
+	public static final String INVALID_DIGIT = "Invalid_Digit"; //$NON-NLS-1$
+	private static final int[] EMPTY_LINE_ENDS = new int[0];
 
 	//----------------optimized identifier managment------------------
 	static final char[] charArray_a = new char[] {'a'}, 
@@ -133,8 +143,60 @@
 
 	static final char[] initCharArray = 
 		new char[] {'\u0000', '\u0000', '\u0000', '\u0000', '\u0000', '\u0000'}; 
-	static final int TableSize = 30, InternalTableSize = 6; //30*6 = 180 entries
-	public static final int OptimizedLength = 6;
+	static final int TableSize = 30, InternalTableSize = 6; //30*6 =210 entries
+	
+	public final static int MAX_OBVIOUS = 128;
+	static final int[] ObviousIdentCharNatures = new int[MAX_OBVIOUS];
+	public final static int C_LETTER = 4;
+	public final static int C_DIGIT = 3;
+	public final static int C_SEPARATOR = 2;
+	public final static int C_SPACE = 1;
+	static {
+		for (int i = '0'; i <= '9'; i++) 
+			ObviousIdentCharNatures[i] = C_DIGIT;
+		
+		for (int i = 'a'; i <= 'z'; i++) 
+			ObviousIdentCharNatures[i] = C_LETTER;
+		for (int i = 'A'; i <= 'Z'; i++) 
+			ObviousIdentCharNatures[i] = C_LETTER;
+		ObviousIdentCharNatures['_'] = C_LETTER;
+		ObviousIdentCharNatures['$'] = C_LETTER;
+		
+		ObviousIdentCharNatures[10] = C_SPACE; // \ u000a: LINE FEED
+		ObviousIdentCharNatures[12] = C_SPACE; // \ u000c: FORM FEED
+		ObviousIdentCharNatures[13] = C_SPACE; //  \ u000d: CARRIAGE RETURN
+		ObviousIdentCharNatures[32] = C_SPACE; //  \ u0020: SPACE
+		ObviousIdentCharNatures[ 9] = C_SPACE; // \ u0009: HORIZONTAL TABULATION
+		
+		ObviousIdentCharNatures['.'] = C_SEPARATOR;
+		ObviousIdentCharNatures[':'] = C_SEPARATOR;
+		ObviousIdentCharNatures[';'] = C_SEPARATOR;
+		ObviousIdentCharNatures[','] = C_SEPARATOR;
+		ObviousIdentCharNatures['['] = C_SEPARATOR;
+		ObviousIdentCharNatures[']'] = C_SEPARATOR;
+		ObviousIdentCharNatures['('] = C_SEPARATOR;
+		ObviousIdentCharNatures[')'] = C_SEPARATOR;
+		ObviousIdentCharNatures['{'] = C_SEPARATOR;
+		ObviousIdentCharNatures['}'] = C_SEPARATOR;
+		ObviousIdentCharNatures['+'] = C_SEPARATOR;
+		ObviousIdentCharNatures['-'] = C_SEPARATOR;
+		ObviousIdentCharNatures['*'] = C_SEPARATOR;
+		ObviousIdentCharNatures['/'] = C_SEPARATOR;
+		ObviousIdentCharNatures['='] = C_SEPARATOR;
+		ObviousIdentCharNatures['&'] = C_SEPARATOR;
+		ObviousIdentCharNatures['|'] = C_SEPARATOR;
+		ObviousIdentCharNatures['?'] = C_SEPARATOR;
+		ObviousIdentCharNatures['<'] = C_SEPARATOR;
+		ObviousIdentCharNatures['>'] = C_SEPARATOR;
+		ObviousIdentCharNatures['!'] = C_SEPARATOR;
+		ObviousIdentCharNatures['%'] = C_SEPARATOR;
+		ObviousIdentCharNatures['^'] = C_SEPARATOR;
+		ObviousIdentCharNatures['~'] = C_SEPARATOR;
+		ObviousIdentCharNatures['"'] = C_SEPARATOR;
+		ObviousIdentCharNatures['\''] = C_SEPARATOR;
+	}
+	
+	public static final int OptimizedLength = 7;
 	public /*static*/ final char[][][][] charArray_length = 
 		new char[OptimizedLength][TableSize][InternalTableSize][]; 
 	// support for detecting non-externalized string literals
@@ -159,7 +221,7 @@
 			}
 		}
 	}
-	static int newEntry2 = 0, 
+	/*static*/ int newEntry2 = 0, 
 		newEntry3 = 0, 
 		newEntry4 = 0, 
 		newEntry5 = 0, 
@@ -169,6 +231,12 @@
 	public static final int SquareBracket = 1;
 	public static final int CurlyBracket = 2;	
 	public static final int BracketKinds = 3;
+	
+	// extended unicode support
+	public static final int LOW_SURROGATE_MIN_VALUE = 0xDC00;
+	public static final int HIGH_SURROGATE_MIN_VALUE = 0xD800;
+	public static final int HIGH_SURROGATE_MAX_VALUE = 0xDBFF;
+	public static final int LOW_SURROGATE_MAX_VALUE = 0xDFFF;
 
 public PublicScanner() {
 	this(false /*comment*/, false /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3 /*sourceLevel*/, null/*taskTag*/, null/*taskPriorities*/, true /*taskCaseSensitive*/);
@@ -179,6 +247,27 @@
 	boolean tokenizeWhiteSpace, 
 	boolean checkNonExternalizedStringLiterals, 
 	long sourceLevel,
+	long complianceLevel,
+	char[][] taskTags,
+	char[][] taskPriorities,
+	boolean isTaskCaseSensitive) {
+
+	this.eofPosition = Integer.MAX_VALUE;
+	this.tokenizeComments = tokenizeComments;
+	this.tokenizeWhiteSpace = tokenizeWhiteSpace;
+	this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
+	this.sourceLevel = sourceLevel;
+	this.complianceLevel = complianceLevel;
+	this.taskTags = taskTags;
+	this.taskPriorities = taskPriorities;
+	this.isTaskCaseSensitive = isTaskCaseSensitive;
+}
+
+public PublicScanner(
+	boolean tokenizeComments, 
+	boolean tokenizeWhiteSpace, 
+	boolean checkNonExternalizedStringLiterals, 
+	long sourceLevel,
 	char[][] taskTags,
 	char[][] taskPriorities,
 	boolean isTaskCaseSensitive) {
@@ -188,6 +277,7 @@
 	this.tokenizeWhiteSpace = tokenizeWhiteSpace;
 	this.checkNonExternalizedStringLiterals = checkNonExternalizedStringLiterals;
 	this.sourceLevel = sourceLevel;
+	this.complianceLevel = sourceLevel;
 	this.taskTags = taskTags;
 	this.taskPriorities = taskPriorities;
 	this.isTaskCaseSensitive = isTaskCaseSensitive;
@@ -208,7 +298,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) {
+public void checkTaskTag(int commentStart, int commentEnd) throws InvalidInputException {
 	char[] src = this.source;
 	
 	// only look for newer task: tags
@@ -322,6 +412,7 @@
 		this.foundTaskMessages[i] = message;
 	}
 }
+
 public char[] getCurrentIdentifierSource() {
 	//return the token REAL source (aka unicodes are precomputed)
 
@@ -354,6 +445,7 @@
 		//no optimization
 		System.arraycopy(this.source, this.startPosition, result = new char[length], 0, length);
 	}
+	//newIdentCount++;
 	return result;
 }
 public int getCurrentTokenEndPosition(){
@@ -382,6 +474,21 @@
 	}
 	return result;
 }
+public final String getCurrentTokenString() {
+	// Return current token as a string
+
+	if (this.withoutUnicodePtr != 0) {
+		// 0 is used as a fast test flag so the real first char is in position 1
+		return new String(
+			this.withoutUnicodeBuffer, 
+			1, 
+			this.withoutUnicodePtr);
+	}
+	return new String(
+		this.source, 
+		this.startPosition, 
+		this.currentPosition - this.startPosition); 
+}
 public final char[] getCurrentTokenSourceString() {
 	//return the token REAL source (aka unicodes are precomputed).
 	//REMOVE the two " that are at the beginning and the end.
@@ -403,7 +510,18 @@
 	}
 	return result;
 }
+public final String getCurrentStringLiteral() {
+	//return the token REAL source (aka unicodes are precomputed).
+	//REMOVE the two " that are at the beginning and the end.
 
+	if (this.withoutUnicodePtr != 0)
+		//0 is used as a fast test flag so the real first char is in position 1
+		//2 is 1 (real start) + 1 (to jump over the ")
+		return new String(this.withoutUnicodeBuffer, 2, this.withoutUnicodePtr - 2);
+	else {
+		return new String(this.source, this.startPosition + 1, this.currentPosition - this.startPosition - 2);
+	}
+}
 public final char[] getRawTokenSource() {
 	int length = this.currentPosition - this.startPosition;
 	char[] tokenSource = new char[length];
@@ -431,7 +549,7 @@
  */
 public final int getLineEnd(int lineNumber) {
 
-	if (this.lineEnds == null) 
+	if (this.lineEnds == null || this.linePtr == -1) 
 		return -1;
 	if (lineNumber > this.lineEnds.length+1) 
 		return -1;
@@ -443,8 +561,10 @@
 }
 
 public final int[] getLineEnds() {
-	//return a bounded copy of this.lineEnds 
-
+	//return a bounded copy of this.lineEnds
+	if (this.linePtr == -1) {
+		return EMPTY_LINE_ENDS;
+	}
 	int[] copy;
 	System.arraycopy(this.lineEnds, 0, copy = new int[this.linePtr + 1], 0, this.linePtr + 1);
 	return copy;
@@ -465,7 +585,7 @@
  */
 public final int getLineStart(int lineNumber) {
 
-	if (this.lineEnds == null) 
+	if (this.lineEnds == null || this.linePtr == -1) 
 		return -1;
 	if (lineNumber > this.lineEnds.length + 1) 
 		return -1;
@@ -480,46 +600,18 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				return -1;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-
-			this.unicodeAsBackSlash = this.currentCharacter == '\\';
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
-			return this.currentCharacter;
-
-		} //-------------end unicode traitement--------------
-		else {
+				getNextUnicodeChar();
+		} else {
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0) {
-			    unicodeStoreAt(++this.withoutUnicodePtr);
+			    unicodeStore();
 			}
-			return this.currentCharacter;
 		}
+		return this.currentCharacter;
 	} catch (IndexOutOfBoundsException e) {
 		return -1;
+	} catch(InvalidInputException e) {
+		return -1;
 	}
 }
 public final boolean getNextChar(char testedChar) {
@@ -542,40 +634,13 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			getNextUnicodeChar();
 			if (this.currentCharacter != testedChar) {
 				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
 				return false;
 			}
-			this.unicodeAsBackSlash = this.currentCharacter == '\\';
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-
 		} //-------------end unicode traitement--------------
 		else {
 			if (this.currentCharacter != testedChar) {
@@ -584,13 +649,17 @@
 			}
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.unicodeAsBackSlash = false;
 		this.currentPosition = temp;
 		return false;
+	} catch(InvalidInputException e) {
+		this.unicodeAsBackSlash = false;
+		this.currentPosition = temp;
+		return false;
 	}
 }
 public final int getNextChar(char testedChar1, char testedChar2) {
@@ -612,62 +681,37 @@
 		int result;
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
+			getNextUnicodeChar();
+			if (this.currentCharacter == testedChar1) {
+				result = 0;
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
 				this.currentPosition = temp;
-				return 2;
+				this.withoutUnicodePtr--;
+				result = -1;
 			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			if (this.currentCharacter == testedChar1)
-				result = 0;
-			else
-				if (this.currentCharacter == testedChar2)
-					result = 1;
-				else {
-					this.currentPosition = temp;
-					return -1;
-				}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return result;
-		} //-------------end unicode traitement--------------
-		else {
-			if (this.currentCharacter == testedChar1)
+		} else {
+			if (this.currentCharacter == testedChar1) {
 				result = 0;
-			else
-				if (this.currentCharacter == testedChar2)
-					result = 1;
-				else {
-					this.currentPosition = temp;
-					return -1;
-				}
+			} else if (this.currentCharacter == testedChar2) {
+				result = 1;
+			} else {
+				this.currentPosition = temp;
+				return -1;
+			}
 
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return result;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.currentPosition = temp;
 		return -1;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return -1;
 	}
 }
 public final boolean getNextCharAsDigit() throws InvalidInputException {
@@ -687,51 +731,28 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			getNextUnicodeChar();
 			if (!isDigit(this.currentCharacter)) {
 				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
 				return false;
 			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-		} //-------------end unicode traitement--------------
-		else {
+		} else {
 			if (!isDigit(this.currentCharacter)) {
 				this.currentPosition = temp;
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.currentPosition = temp;
 		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
 	}
 }
 public final boolean getNextCharAsDigit(int radix) {
@@ -751,51 +772,28 @@
 	try {
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
-				return false;
-			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			getNextUnicodeChar();
 			if (Character.digit(this.currentCharacter, radix) == -1) {
 				this.currentPosition = temp;
+				this.withoutUnicodePtr--;
 				return false;
 			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-		} //-------------end unicode traitement--------------
-		else {
+		} else {
 			if (Character.digit(this.currentCharacter, radix) == -1) {
 				this.currentPosition = temp;
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
 		this.currentPosition = temp;
 		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = temp;
+		return false;
 	}
 }
 public boolean getNextCharAsJavaIdentifierPart() {
@@ -808,58 +806,67 @@
 	//On false, no side effect has occured.
 
 	//ALL getNextChar.... ARE OPTIMIZED COPIES 
-	if (this.currentPosition >= this.source.length) // handle the obvious case upfront
+	int pos;
+	if ((pos = this.currentPosition) >= this.source.length) // handle the obvious case upfront
 		return false;
 
-	int temp = this.currentPosition;
+	int temp2 = this.withoutUnicodePtr;
 	try {
+		boolean unicode = false;
 		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 			&& (this.source[this.currentPosition] == 'u')) {
-			//-------------unicode traitement ------------
-			int c1, c2, c3, c4;
-			int unicodeSize = 6;
-			this.currentPosition++;
-			while (this.source[this.currentPosition] == 'u') {
-				this.currentPosition++;
-				unicodeSize++;
-			}
-
-			if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-				|| c1 < 0)
-				|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-				|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-				|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-				this.currentPosition = temp;
+			getNextUnicodeChar();
+			unicode = true;
+		}
+		char c = this.currentCharacter;
+		boolean isJavaIdentifierPart = false;
+		if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+			if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
 				return false;
 			}
-
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			if (!Character.isJavaIdentifierPart(this.currentCharacter)) {
-				this.currentPosition = temp;
+			// Unicode 4 detection
+			char low = (char) getNextChar();
+			if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+				// illegal low surrogate
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
 				return false;
 			}
-
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
+			isJavaIdentifierPart = ScannerHelper.isJavaIdentifierPart(c, low);
+		}
+		else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+			this.currentPosition = pos;
+			this.withoutUnicodePtr = temp2;
+			return false;
+		} else {
+			isJavaIdentifierPart = Character.isJavaIdentifierPart(c);
+		}
+		if (unicode) {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
+				this.withoutUnicodePtr = temp2;
+				return false;
 			}
-			//fill the buffer with the char
-		    unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
-		} //-------------end unicode traitement--------------
-		else {
-			if (!Character.isJavaIdentifierPart(this.currentCharacter)) {
-				this.currentPosition = temp;
+		} else {
+			if (!isJavaIdentifierPart) {
+				this.currentPosition = pos;
 				return false;
 			}
 
 			if (this.withoutUnicodePtr != 0)
-			    unicodeStoreAt(++this.withoutUnicodePtr);
+			    unicodeStore();
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
-		this.currentPosition = temp;
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
+		return false;
+	} catch(InvalidInputException e) {
+		this.currentPosition = pos;
+		this.withoutUnicodePtr = temp2;
 		return false;
 	}
 }
@@ -879,10 +886,13 @@
 			// ---------Consume white space and handles startPosition---------
 			whiteStart = this.currentPosition;
 			boolean isWhiteSpace, hasWhiteSpaces = false;
-			int offset = 0;
+			int offset;
+			int unicodePtr;
+			boolean checkIfUnicode = false;
 			do {
+				unicodePtr = this.withoutUnicodePtr;
+				offset = this.currentPosition;
 				this.startPosition = this.currentPosition;
-				boolean checkIfUnicode = false;
 				try {
 					checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 						&& (this.source[this.currentPosition] == 'u');
@@ -898,9 +908,9 @@
 				}
 				if (checkIfUnicode) {
 					isWhiteSpace = jumpOverUnicodeWhiteSpace();
-					offset = 6;
+					offset = this.currentPosition - offset;
 				} else {
-					offset = 1;
+					offset = this.currentPosition - offset;
 					if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
 						checkNonExternalizedString();
 						if (this.recordLineSeparator) {
@@ -909,18 +919,40 @@
 							this.currentLine = null;
 						}
 					}
-					isWhiteSpace = 
-						(this.currentCharacter == ' ') || CharOperation.isWhitespace(this.currentCharacter); 
+					// inline version of:
+					//isWhiteSpace = 
+					//	(this.currentCharacter == ' ') || CharOperation.isWhitespace(this.currentCharacter); 
+					switch (this.currentCharacter) {
+						case 10 : /* \ u000a: LINE FEED               */
+						case 12 : /* \ u000c: FORM FEED               */
+						case 13 : /* \ u000d: CARRIAGE RETURN         */
+						case 32 : /* \ u0020: SPACE                   */
+						case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+							isWhiteSpace = true;
+							break;
+						default :
+							isWhiteSpace = false;
+					}
 				}
 				if (isWhiteSpace) {
 					hasWhiteSpaces = true;
 				}
 			} while (isWhiteSpace);
-			if (this.tokenizeWhiteSpace && hasWhiteSpaces) {
-				// reposition scanner in case we are interested by spaces as tokens
-				this.currentPosition-=offset;
-				this.startPosition = whiteStart;
-				return TokenNameWHITESPACE;
+			if (hasWhiteSpaces) {
+				if (this.tokenizeWhiteSpace) {
+					// reposition scanner in case we are interested by spaces as tokens
+					this.currentPosition-=offset;
+					this.startPosition = whiteStart;
+					if (checkIfUnicode) {
+						this.withoutUnicodePtr = unicodePtr;
+					}
+					return TokenNameWHITESPACE;
+				} else if (checkIfUnicode) {
+					this.withoutUnicodePtr = 0;
+					unicodeStore();
+				} else {
+					this.withoutUnicodePtr = 0;
+				}
 			}
 			//little trick to get out in the middle of a source compuation
 			if (this.currentPosition > this.eofPosition)
@@ -1113,11 +1145,24 @@
 						}
 						throw new InvalidInputException(INVALID_CHARACTER_CONSTANT);
 					}
-					if (getNextChar('\\'))
+					if (getNextChar('\\')) {
+						if (this.unicodeAsBackSlash) {
+							// consume next character
+							this.unicodeAsBackSlash = false;
+							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+								getNextUnicodeChar();
+							} else {
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
+								}
+							}
+						} else {
+							this.currentCharacter = this.source[this.currentPosition++];
+						}
 						scanEscapeCharacter();
-					else { // consume next character
+					} else { // consume next character
 						this.unicodeAsBackSlash = false;
-						boolean checkIfUnicode = false;
+						checkIfUnicode = false;
 						try {
 							checkIfUnicode = ((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 							&& (this.source[this.currentPosition] == 'u');
@@ -1129,7 +1174,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 					}
@@ -1158,7 +1203,7 @@
 							isUnicode = true;
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 
@@ -1193,20 +1238,25 @@
 								throw new InvalidInputException(INVALID_CHAR_IN_STRING);
 							}
 							if (this.currentCharacter == '\\') {
-								int escapeSize = this.currentPosition;
-								boolean backSlashAsUnicodeInString = this.unicodeAsBackSlash;
-								//scanEscapeCharacter make a side effect on this value and we need the previous value few lines down this one
-								scanEscapeCharacter();
-								escapeSize = this.currentPosition - escapeSize;
-								if (this.withoutUnicodePtr == 0) {
-									//buffer all the entries that have been left aside....
-								    unicodeInitializeBuffer(this.currentPosition - escapeSize - 1 - this.startPosition);
-								    unicodeStoreAt(++this.withoutUnicodePtr);
-								} else { //overwrite the / in the buffer
-								    unicodeStoreAt(this.withoutUnicodePtr);
-									if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
+								if (this.unicodeAsBackSlash) {
+									this.withoutUnicodePtr--;
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
 										this.withoutUnicodePtr--;
 									}
+								} else {
+									if (this.withoutUnicodePtr == 0) {
+										unicodeInitializeBuffer(this.currentPosition - this.startPosition);
+									}
+									this.withoutUnicodePtr --;
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
+								// we need to compute the escape character in a separate buffer
+								scanEscapeCharacter();
+								if (this.withoutUnicodePtr != 0) {
+									unicodeStore();
 								}
 							}
 							// consume next character
@@ -1216,7 +1266,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									unicodeStoreAt(++this.withoutUnicodePtr);
+									unicodeStore();
 								}
 							}
 
@@ -1259,25 +1309,8 @@
 							this.lastCommentLinePosition = this.currentPosition;
 							try { //get the next char 
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
-									//-------------unicode traitement ------------
-									int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-									this.currentPosition++;
-									while (this.source[this.currentPosition] == 'u') {
-										this.currentPosition++;
-									}
-									if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c1 < 0
-										|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c2 < 0
-										|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c3 < 0
-										|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c4 < 0) {
-										throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-									} else {
-										this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-									}
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
 								}
 
 								//handle the \\u case manually into comment
@@ -1291,26 +1324,9 @@
 									//get the next char
 									isUnicode = false;									
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-										&& (this.source[this.currentPosition] == 'u')) {
-										isUnicode = true;											
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										this.currentPosition++;
-										while (this.source[this.currentPosition] == 'u') {
-											this.currentPosition++;
-										}
-										if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c4 < 0) {
-											throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-										} else {
-											this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
+											&& (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+										isUnicode = true;
 									}
 									//handle the \\u case manually into comment
 									if (this.currentCharacter == '\\') {
@@ -1328,32 +1344,8 @@
 										this.currentCharacter = '\n';
 								   	} else if ((this.source[this.currentPosition] == '\\')
 										&& (this.source[this.currentPosition + 1] == 'u')) {
+										getNextUnicodeChar();
 										isUnicode = true;
-										char unicodeChar;
-										int index = this.currentPosition + 1;
-										index++;
-										while (this.source[index] == 'u') {
-											index++;
-										}
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										if ((c1 = Character.getNumericValue(this.source[index++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[index++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[index++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[index++])) > 15
-											|| c4 < 0) {
-											this.currentPosition = index;
-											throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-										} else {
-											unicodeChar = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
-										if (unicodeChar == '\n') {
-											this.currentPosition = index;
-											this.currentCharacter = '\n';
-										}
 									}
 							   	}
 								recordComment(TokenNameCOMMENT_LINE);
@@ -1389,6 +1381,7 @@
 							try { //get the next char
 								boolean isJavadoc = false, star = false;
 								boolean isUnicode = false;
+								int previous;
 								// consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
@@ -1398,10 +1391,10 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-										unicodeStoreAt(++this.withoutUnicodePtr);
+										unicodeStore();
 									}
 								}
-	
+
 								if (this.currentCharacter == '*') {
 									isJavadoc = true;
 									star = true;
@@ -1419,6 +1412,7 @@
 									}
 								}
 								isUnicode = false;
+								previous = this.currentPosition;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 									&& (this.source[this.currentPosition] == 'u')) {
 									//-------------unicode traitement ------------
@@ -1437,6 +1431,7 @@
 									isJavadoc = false;
 								}
 								//loop until end of comment */
+								int firstTag = 0;
 								while ((this.currentCharacter != '/') || (!star)) {
 									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
 										checkNonExternalizedString();
@@ -1450,8 +1445,20 @@
 											this.currentLine = null;
 										}
 									}
-									star = this.currentCharacter == '*';
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0) {
+												firstTag = previous;
+											}
+											// fall through default case to set star to false
+										default:
+											star = false;
+									}
 									//get next char
+									previous = this.currentPosition;
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
 										&& (this.source[this.currentPosition] == 'u')) {
 										//-------------unicode traitement ------------
@@ -1468,6 +1475,7 @@
 								}
 								int token = isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK;
 								recordComment(token);
+								this.commentTagStarts[this.commentPtr] = firstTag;
 								if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition);
 								if (this.tokenizeComments) {
 									/*
@@ -1494,7 +1502,37 @@
 					throw new InvalidInputException("Ctrl-Z"); //$NON-NLS-1$
 
 				default :
-					if (Character.isJavaIdentifierStart(this.currentCharacter))
+					char c = this.currentCharacter;
+					if (c < MAX_OBVIOUS) {
+						switch (ObviousIdentCharNatures[c]) {
+							case C_LETTER :
+								return scanIdentifierOrKeyword();
+							case C_DIGIT :
+								return scanNumber(false);
+						}
+					}
+					boolean isJavaIdStart;
+					if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						// Unicode 4 detection
+						char low = (char) getNextChar();
+						if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+							// illegal low surrogate
+							throw new InvalidInputException(INVALID_LOW_SURROGATE);
+						}
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
+					}
+					else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+							throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+						}
+						throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+					} else {
+						isJavaIdStart = Character.isJavaIdentifierStart(c);
+					}
+					if (isJavaIdStart)
 						return scanIdentifierOrKeyword();
 					if (isDigit(this.currentCharacter)) {
 						return scanNumber(false);
@@ -1513,7 +1551,7 @@
 	}
 	return TokenNameEOF;
 }
-public final void getNextUnicodeChar()
+public void getNextUnicodeChar()
 	throws InvalidInputException {
 	//VOID
 	//handle the case of unicode.
@@ -1540,16 +1578,15 @@
 			|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
 			|| c4 < 0){
 			throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-		} else {
-			this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-			//need the unicode buffer
-			if (this.withoutUnicodePtr == 0) {
-				//buffer all the entries that have been left aside....
-				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
-			}
-			//fill the buffer with the char
-			unicodeStoreAt(++this.withoutUnicodePtr);
 		}
+		this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+		//need the unicode buffer
+		if (this.withoutUnicodePtr == 0) {
+			//buffer all the entries that have been left aside....
+			unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
+		}
+		//fill the buffer with the char
+		unicodeStore();
 		this.unicodeAsBackSlash = this.currentCharacter == '\\';
 	} catch (ArrayIndexOutOfBoundsException e) {
 		this.currentPosition--;
@@ -1560,6 +1597,7 @@
 public char[] getSource(){
 	return this.source;
 }
+// TODO (philippe) should simply switch on character
 protected boolean isDigit(char c) throws InvalidInputException {
 	if (Character.isDigit(c)) {
 		switch(c) {
@@ -1580,8 +1618,6 @@
 		return false;
 	}
 }
-/* Tokenize a method body, assuming that curly brackets are properly balanced.
- */
 public final void jumpOverMethodBody() {
 
 	this.wasAcr = false;
@@ -1604,21 +1640,34 @@
 			} while (isWhiteSpace);
 
 			// -------consume token until } is found---------
-			switch (this.currentCharacter) {
+			NextToken: switch (this.currentCharacter) {
 				case '{' :
 					found++;
-					break;
+					break NextToken;
 				case '}' :
 					found--;
 					if (found == 0)
 						return;
-					break;
+					break NextToken;
 				case '\'' :
 					{
 						boolean test;
 						test = getNextChar('\\');
 						if (test) {
 							try {
+								if (this.unicodeAsBackSlash) {
+									// consume next character
+									this.unicodeAsBackSlash = false;
+									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+										getNextUnicodeChar();
+									} else {
+										if (this.withoutUnicodePtr != 0) {
+											unicodeStore();
+										}
+									}
+								} else {
+									this.currentCharacter = this.source[this.currentPosition++];
+								}
 								scanEscapeCharacter();
 							} catch (InvalidInputException ex) {
 								// ignore
@@ -1627,11 +1676,11 @@
 							try { // consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										unicodeStoreAt(++this.withoutUnicodePtr);
+										unicodeStore();
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1639,18 +1688,18 @@
 							}
 						}
 						getNextChar('\'');
-						break;
+						break NextToken;
 					}
 				case '"' :
 					try {
 						try { // consume next character
 							this.unicodeAsBackSlash = false;
 							if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-								&& (this.source[this.currentPosition] == 'u')) {
+									&& (this.source[this.currentPosition] == 'u')) {
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-								    unicodeStoreAt(++this.withoutUnicodePtr);
+								    unicodeStore();
 								}
 							}
 						} catch (InvalidInputException ex) {
@@ -1659,13 +1708,26 @@
 						while (this.currentCharacter != '"') {
 							if (this.currentCharacter == '\r'){
 								if (this.source[this.currentPosition] == '\n') this.currentPosition++;
-								break; // the string cannot go further that the line
+								break NextToken; // the string cannot go further that the line
 							}
 							if (this.currentCharacter == '\n'){
 								break; // the string cannot go further that the line
 							}
 							if (this.currentCharacter == '\\') {
 								try {
+									if (this.unicodeAsBackSlash) {
+										// consume next character
+										this.unicodeAsBackSlash = false;
+										if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
+											getNextUnicodeChar();
+										} else {
+											if (this.withoutUnicodePtr != 0) {
+												unicodeStore();
+											}
+										}
+									} else {
+										this.currentCharacter = this.source[this.currentPosition++];
+									}
 									scanEscapeCharacter();
 								} catch (InvalidInputException ex) {
 									// ignore
@@ -1674,11 +1736,11 @@
 							try { // consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										unicodeStoreAt(++this.withoutUnicodePtr);
+										unicodeStore();
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1688,7 +1750,7 @@
 					} catch (IndexOutOfBoundsException e) {
 						return;
 					}
-					break;
+					break NextToken;
 				case '/' :
 					{
 						int test;
@@ -1697,26 +1759,8 @@
 								this.lastCommentLinePosition = this.currentPosition;
 								//get the next char 
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
-									//-------------unicode traitement ------------
-									int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-									this.currentPosition++;
-									while (this.source[this.currentPosition] == 'u') {
-										this.currentPosition++;
-									}
-									if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c1 < 0
-										|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c2 < 0
-										|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c3 < 0
-										|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-										|| c4 < 0) { //error don't care of the value
-										this.currentCharacter = 'A';
-									} //something different from \n and \r
-									else {
-										this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-									}
+										&& (this.source[this.currentPosition] == 'u')) {
+									getNextUnicodeChar();
 								}
 								//handle the \\u case manually into comment
 								if (this.currentCharacter == '\\') {
@@ -1729,27 +1773,9 @@
 									//get the next char 
 									isUnicode = false;
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-										&& (this.source[this.currentPosition] == 'u')) {
+											&& (this.source[this.currentPosition] == 'u')) {
 										isUnicode = true;
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										this.currentPosition++;
-										while (this.source[this.currentPosition] == 'u') {
-											this.currentPosition++;
-										}
-										if ((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-											|| c4 < 0) { //error don't care of the value
-											this.currentCharacter = 'A';
-										} //something different from \n and \r
-										else {
-											this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
+										getNextUnicodeChar();
 									}
 									//handle the \\u case manually into comment
 									if (this.currentCharacter == '\\') {
@@ -1766,32 +1792,9 @@
 										this.currentPosition++;
 										this.currentCharacter = '\n';
 								   	} else if ((this.source[this.currentPosition] == '\\')
-										&& (this.source[this.currentPosition + 1] == 'u')) {
+											&& (this.source[this.currentPosition + 1] == 'u')) {
 										isUnicode = true;
-										char unicodeChar;
-										int index = this.currentPosition + 1;
-										index++;
-										while (this.source[index] == 'u') {
-											index++;
-										}
-										//-------------unicode traitement ------------
-										int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
-										if ((c1 = Character.getNumericValue(this.source[index++])) > 15
-											|| c1 < 0
-											|| (c2 = Character.getNumericValue(this.source[index++])) > 15
-											|| c2 < 0
-											|| (c3 = Character.getNumericValue(this.source[index++])) > 15
-											|| c3 < 0
-											|| (c4 = Character.getNumericValue(this.source[index++])) > 15
-											|| c4 < 0) { //error don't care of the value
-											unicodeChar = 'A';
-										} else {
-											unicodeChar = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-										}
-										if (unicodeChar == '\n') {
-											this.currentPosition = index;
-											this.currentCharacter = '\n';
-										}
+										getNextUnicodeChar();
 									}
 							   	}
 								recordComment(TokenNameCOMMENT_LINE);
@@ -1811,23 +1814,24 @@
 									this.currentPosition++; 
 								}
 							}
-							break;
+							break NextToken;
 						}
 						if (test > 0) { //traditional and javadoc comment
 							boolean isJavadoc = false;
 							try { //get the next char
 								boolean star = false;
+								int previous;
 								boolean isUnicode = false;
 								// consume next character
 								this.unicodeAsBackSlash = false;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 									isUnicode = true;
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-    								    unicodeStoreAt(++this.withoutUnicodePtr);
+    								    unicodeStore();
 									}
 								}
 	
@@ -1847,9 +1851,9 @@
 									}
 								}
 								isUnicode = false;
+								previous = this.currentPosition;
 								if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-									&& (this.source[this.currentPosition] == 'u')) {
-									//-------------unicode traitement ------------
+										&& (this.source[this.currentPosition] == 'u')) {
 									getNextUnicodeChar();
 									isUnicode = true;
 								} else {
@@ -1865,6 +1869,7 @@
 									isJavadoc = false;
 								}
 								//loop until end of comment */
+								int firstTag = 0;
 								while ((this.currentCharacter != '/') || (!star)) {
 									if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) {
 										if (this.recordLineSeparator) {
@@ -1877,11 +1882,22 @@
 											this.currentLine = null;
 										}
 									}
-									star = this.currentCharacter == '*';
+									switch (this.currentCharacter) {
+										case '*':
+											star = true;
+											break;
+										case '@':
+											if (firstTag == 0) {
+												firstTag = previous;
+											}
+											// fall through default case to set star to false
+										default:
+											star = false;
+									}
 									//get next char
+									previous = this.currentPosition;
 									if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\')
-										&& (this.source[this.currentPosition] == 'u')) {
-										//-------------unicode traitement ------------
+											&& (this.source[this.currentPosition] == 'u')) {
 										getNextUnicodeChar();
 										isUnicode = true;
 									} else {
@@ -1894,26 +1910,59 @@
 									} //jump over the \\
 								}
 								recordComment(isJavadoc ? TokenNameCOMMENT_JAVADOC : TokenNameCOMMENT_BLOCK);
+								this.commentTagStarts[this.commentPtr] = firstTag;
 							} catch (IndexOutOfBoundsException e) {
 								return;
 							}
-							break;
+							break NextToken;
 						}
-						break;
+						break NextToken;
 					}
 
 				default :
-					if (Character.isJavaIdentifierStart(this.currentCharacter)) {
-						scanIdentifierOrKeyword();
-						break;
-					}
-					if (isDigit(this.currentCharacter)) {
-						try {
+					try {
+						char c = this.currentCharacter;
+						if (c < MAX_OBVIOUS) {
+							switch (ObviousIdentCharNatures[c]) {
+								case C_LETTER :
+									scanIdentifierOrKeyword();
+									break NextToken;
+								case C_DIGIT :
+									scanNumber(false);
+									break NextToken;
+							}
+						}
+						boolean isJavaIdStart;
+						if (c >= HIGH_SURROGATE_MIN_VALUE && c <= HIGH_SURROGATE_MAX_VALUE) {
+							if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+								throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+							}
+							// Unicode 4 detection
+							char low = (char) getNextChar();
+							if (low < LOW_SURROGATE_MIN_VALUE || low > LOW_SURROGATE_MAX_VALUE) {
+								// illegal low surrogate
+								throw new InvalidInputException(INVALID_LOW_SURROGATE);
+							}
+							isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
+						}
+						else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
+							if (this.complianceLevel < ClassFileConstants.JDK1_5) {
+								throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
+							}
+							throw new InvalidInputException(INVALID_HIGH_SURROGATE);
+						} else {
+							isJavaIdStart = Character.isJavaIdentifierStart(c);
+						}
+						if (isJavaIdStart) {
+							scanIdentifierOrKeyword();
+							break NextToken;
+						}
+						if (isDigit(this.currentCharacter)) {
 							scanNumber(false);
-						} catch (InvalidInputException ex) {
- 							// ignore
- 						}
-						break;
+							break NextToken;
+						}						
+					} catch (InvalidInputException ex) {
+						// ignore
 					}
 			}
 		}
@@ -1934,30 +1983,8 @@
 
 	try {
 		this.wasAcr = false;
-		int c1, c2, c3, c4;
-		int unicodeSize = 6;
-		this.currentPosition++;
-		while (this.source[this.currentPosition] == 'u') {
-			this.currentPosition++;
-			unicodeSize++;
-		}
-
-		if (((c1 = Character.getNumericValue(this.source[this.currentPosition++])) > 15
-			|| c1 < 0)
-			|| ((c2 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c2 < 0)
-			|| ((c3 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c3 < 0)
-			|| ((c4 = Character.getNumericValue(this.source[this.currentPosition++])) > 15 || c4 < 0)) {
-			throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
-		}
-
-		this.currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
-		if (CharOperation.isWhitespace(this.currentCharacter))
-			return true;
-
-		//buffer the new char which is not a white space
-		unicodeStoreAt(++this.withoutUnicodePtr);
-		//this.withoutUnicodePtr == 1 is true here
-		return false;
+		getNextUnicodeChar();
+		return CharOperation.isWhitespace(this.currentCharacter);
 	} catch (IndexOutOfBoundsException e){
 		this.currentPosition--;
 		throw new InvalidInputException(INVALID_UNICODE_ESCAPE);
@@ -2029,10 +2056,10 @@
 final char[] optimizedCurrentTokenSource2() {
 	//try to return the same char[] build only once
 
-	char c0, c1;
-	int hash = 
-		(((c0 = this.source[this.startPosition]) << 6) + (c1 = this.source[this.startPosition + 1]))
-			% TableSize; 
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0 , c1;
+	int hash = (((c0=src[start]) << 6) + (c1=src[start+1])) % TableSize; 
 	char[][] table = this.charArray_length[0][hash];
 	int i = newEntry2;
 	while (++i < InternalTableSize) {
@@ -2051,19 +2078,18 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1});
-	newEntry2 = max;
-	return r;
+	System.arraycopy(src, start, r= new char[2], 0, 2);
+	//newIdentCount++;
+	return table[newEntry2 = max] = r; //(r = new char[] {c0, c1});
 }
 final char[] optimizedCurrentTokenSource3() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2;
-	int hash = 
-		(((c0 = this.source[this.startPosition]) << 12)
-			+ ((c1 = this.source[this.startPosition + 1]) << 6)
-			+ (c2 = this.source[this.startPosition + 2]))
-			% TableSize; 
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1=src[start+1], c2;
+	int hash = (((c0=src[start])<< 6) + (c2=src[start+2])) % TableSize; 
+//	int hash = ((c0 << 12) + (c1<< 6) + c2) % TableSize; 
 	char[][] table = this.charArray_length[1][hash];
 	int i = newEntry3;
 	while (++i < InternalTableSize) {
@@ -2082,21 +2108,19 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2});
-	newEntry3 = max;
-	return r;
+	System.arraycopy(src, start, r= new char[3], 0, 3);
+	//newIdentCount++;
+	return table[newEntry3 = max] = r; //(r = new char[] {c0, c1, c2});
 }
 final char[] optimizedCurrentTokenSource4() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2, c3;
-	long hash = 
-		((((long) (c0 = this.source[this.startPosition])) << 18)
-			+ ((c1 = this.source[this.startPosition + 1]) << 12)
-			+ ((c2 = this.source[this.startPosition + 2]) << 6)
-			+ (c3 = this.source[this.startPosition + 3]))
-			% TableSize; 
-	char[][] table = this.charArray_length[2][(int) hash];
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3];
+	int hash = (((c0=src[start]) << 6) + (c2=src[start+2])) % TableSize;
+//	int hash = (int) (((((long) c0) << 18) + (c1 << 12) + (c2 << 6) + c3) % TableSize); 
+	char[][] table = this.charArray_length[2][hash];
 	int i = newEntry4;
 	while (++i < InternalTableSize) {
 		char[] charArray = table[i];
@@ -2120,23 +2144,19 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2, c3});
-	newEntry4 = max;
-	return r;
-	
+	System.arraycopy(src, start, r= new char[4], 0, 4);
+	//newIdentCount++;
+	return table[newEntry4 = max] = r; //(r = new char[] {c0, c1, c2, c3});
 }
 final char[] optimizedCurrentTokenSource5() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2, c3, c4;
-	long hash = 
-		((((long) (c0 = this.source[this.startPosition])) << 24)
-			+ (((long) (c1 = this.source[this.startPosition + 1])) << 18)
-			+ ((c2 = this.source[this.startPosition + 2]) << 12)
-			+ ((c3 = this.source[this.startPosition + 3]) << 6)
-			+ (c4 = this.source[this.startPosition + 4]))
-			% TableSize; 
-	char[][] table = this.charArray_length[3][(int) hash];
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4;
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int) (((((long) c0) << 24) + (((long) c1) << 18) + (c2 << 12) + (c3 << 6) + c4) % TableSize); 
+	char[][] table = this.charArray_length[3][hash];
 	int i = newEntry5;
 	while (++i < InternalTableSize) {
 		char[] charArray = table[i];
@@ -2162,24 +2182,19 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2, c3, c4});
-	newEntry5 = max;
-	return r;
-		
+	System.arraycopy(src, start, r= new char[5], 0, 5);
+	//newIdentCount++;
+	return table[newEntry5 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4});
 }
 final char[] optimizedCurrentTokenSource6() {
 	//try to return the same char[] build only once
 
-	char c0, c1, c2, c3, c4, c5;
-	long hash = 
-		((((long) (c0 = this.source[this.startPosition])) << 32)
-			+ (((long) (c1 = this.source[this.startPosition + 1])) << 24)
-			+ (((long) (c2 = this.source[this.startPosition + 2])) << 18)
-			+ ((c3 = this.source[this.startPosition + 3]) << 12)
-			+ ((c4 = this.source[this.startPosition + 4]) << 6)
-			+ (c5 = this.source[this.startPosition + 5]))
-			% TableSize; 
-	char[][] table = this.charArray_length[4][(int) hash];
+	char[] src = this.source;
+	int start = this.startPosition;
+	char c0, c1 = src[start+1], c2, c3 = src[start+3], c4, c5 = src[start+5];
+	int hash = (((c0=src[start]) << 12) +((c2=src[start+2]) << 6) + (c4=src[start+4])) % TableSize;
+//	int hash = (int)(((((long) c0) << 32) + (((long) c1) << 24) + (((long) c2) << 18) + (c3 << 12) + (c4 << 6) + c5) % TableSize); 
+	char[][] table = this.charArray_length[4][hash];
 	int i = newEntry6;
 	while (++i < InternalTableSize) {
 		char[] charArray = table[i];
@@ -2207,10 +2222,11 @@
 	//--------add the entry-------
 	if (++max >= InternalTableSize) max = 0;
 	char[] r;
-	table[max] = (r = new char[] {c0, c1, c2, c3, c4, c5});
-	newEntry6 = max;
-	return r;	
+	System.arraycopy(src, start, r= new char[6], 0, 6);
+	//newIdentCount++;
+	return table[newEntry6 = max] = r; //(r = new char[] {c0, c1, c2, c3, c4, c5});
 }
+
 protected void parseTags(NLSLine line) {
 	String s = new String(getCurrentTokenSource());
 	int pos = s.indexOf(TAG_PREFIX);
@@ -2326,6 +2342,7 @@
 		}
 	}
 }
+
 public void recordComment(int token) {
 	// compute position
 	int stopPosition = this.currentPosition;
@@ -2341,9 +2358,10 @@
 	// a new comment is recorded
 	int length = this.commentStops.length;
 	if (++this.commentPtr >=  length) {
-		System.arraycopy(this.commentStops, 0, this.commentStops = new int[length + 30], 0, length);
-		//grows the positions buffers too
-		System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[length + 30], 0, length);
+		int newLength = length + COMMENT_ARRAYS_SIZE*10;
+		System.arraycopy(this.commentStops, 0, this.commentStops = new int[newLength], 0, length);
+		System.arraycopy(this.commentStarts, 0, this.commentStarts = new int[newLength], 0, length);
+		System.arraycopy(this.commentTagStarts, 0, this.commentTagStarts = new int[newLength], 0, length);
 	}
 	this.commentStops[this.commentPtr] = stopPosition;
 	this.commentStarts[this.commentPtr] = this.startPosition;
@@ -2361,7 +2379,11 @@
 
 	this.diet = false;
 	this.initialPosition = this.startPosition = this.currentPosition = begin;
-	this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+	if (this.source != null && this.source.length < end) {
+		this.eofPosition = this.source.length;
+	} else {
+		this.eofPosition = end < Integer.MAX_VALUE ? end + 1 : end;
+	}
 	this.commentPtr = -1; // reset comment stack
 	this.foundTaskCount = 0;
 	
@@ -2374,19 +2396,6 @@
 public final void scanEscapeCharacter() throws InvalidInputException {
 	// the string with "\\u" is a legal string of two chars \ and u
 	//thus we use a direct access to the source (for regular cases).
-
-	if (this.unicodeAsBackSlash) {
-		// consume next character
-		this.unicodeAsBackSlash = false;
-		if (((this.currentCharacter = this.source[this.currentPosition++]) == '\\') && (this.source[this.currentPosition] == 'u')) {
-			getNextUnicodeChar();
-		} else {
-			if (this.withoutUnicodePtr != 0) {
-				unicodeStoreAt(++this.withoutUnicodePtr);
-			}
-		}
-	} else
-		this.currentCharacter = this.source[this.currentPosition++];
 	switch (this.currentCharacter) {
 		case 'b' :
 			this.currentCharacter = '\b';
@@ -2461,11 +2470,45 @@
 	//dispatch on the second char 
 	this.useAssertAsAnIndentifier = false;
 	this.useEnumAsAnIndentifier = false;
-	while (getNextCharAsJavaIdentifierPart()){/*empty*/}
 
+	char[] src = this.source;
+	identLoop: {
+		int pos, srcLength = this.source.length;
+		while (true) {
+			if ((pos = this.currentPosition) >= srcLength) // handle the obvious case upfront
+				break identLoop;
+			char c = src[pos];
+			if (c < MAX_OBVIOUS) {
+				switch (ObviousIdentCharNatures[c]) {
+					case C_LETTER :
+					case C_DIGIT :
+		               if (this.withoutUnicodePtr != 0) {
+							this.currentCharacter = c;
+							unicodeStore();
+						}
+						this.currentPosition++;
+						break;						
+						
+					case C_SEPARATOR :
+					case C_SPACE :
+						this.currentCharacter = c;
+						break identLoop;	
+
+					default:
+						//System.out.println("slow<=128:  "+ c);						
+						while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+						break identLoop;						
+				}
+			} else {
+				//System.out.println("slow>>128:  "+ c);						
+				while (getNextCharAsJavaIdentifierPart()){/*empty*/}
+				break identLoop;						
+			}
+		}
+	}
+	
 	int index, length;
 	char[] data;
-	char firstLetter;
 	if (this.withoutUnicodePtr == 0)
 
 		//quick test on length == 1 but not on length > 12 while most identifier
@@ -2484,8 +2527,8 @@
 		index = 1;
 	}
 
-	firstLetter = data[index];
-	switch (firstLetter) {
+
+	switch (data[index]) {
 
 		case 'a' : 
 			switch(length) {
@@ -2580,7 +2623,7 @@
 							&& (data[++index] == 'n')
 							&& (data[++index] == 's')
 							&& (data[++index] == 't'))
-							return TokenNameERROR; //const is not used in java ???????
+							return TokenNameconst; //const is not used in java ???????
 						else
 							return TokenNameIdentifier;
 				case 8 :
@@ -2708,7 +2751,7 @@
 				if ((data[++index] == 'o')
 					&& (data[++index] == 't')
 					&& (data[++index] == 'o')) {
-					return TokenNameERROR;
+					return TokenNamegoto;
 				}
 			} //no goto in java are allowed, so why java removes this keyword ???
 			return TokenNameIdentifier;
@@ -3034,6 +3077,8 @@
 			return TokenNameIdentifier;
 	}
 }
+
+
 public int scanNumber(boolean dotPrefix) throws InvalidInputException {
 
 	//when entering this method the currentCharacter is the first
@@ -3053,11 +3098,13 @@
 				return TokenNameLongLiteral;
 			} else if (getNextChar('.')) {
 				if (this.sourceLevel < ClassFileConstants.JDK1_5) {
-					// if we are in source level < 1.5, we report an integer literal
+					if (end == start) {
+						throw new InvalidInputException(INVALID_HEXA);
+					}
 					this.currentPosition = end;
 					return TokenNameIntegerLiteral;
 				}
-				// hexadeciman floating point literal
+				// hexadecimal floating point literal
 				// read decimal part
 				boolean hasNoDigitsBeforeDot = end == start;
 				start = this.currentPosition;
@@ -3074,7 +3121,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							unicodeStoreAt(++this.withoutUnicodePtr);
+							unicodeStore();
 						}
 					}
 
@@ -3086,7 +3133,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 					}
@@ -3119,7 +3166,7 @@
 					getNextUnicodeChar();
 				} else {
 					if (this.withoutUnicodePtr != 0) {
-						unicodeStoreAt(++this.withoutUnicodePtr);
+						unicodeStore();
 					}
 				}
 
@@ -3131,7 +3178,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							unicodeStoreAt(++this.withoutUnicodePtr);
+							unicodeStore();
 						}
 					}
 				}
@@ -3182,7 +3229,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							unicodeStoreAt(++this.withoutUnicodePtr);
+							unicodeStore();
 						}
 					}
 
@@ -3194,7 +3241,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								unicodeStoreAt(++this.withoutUnicodePtr);
+								unicodeStore();
 							}
 						}
 					}
@@ -3234,7 +3281,7 @@
 			getNextUnicodeChar();
 		} else {
 			if (this.withoutUnicodePtr != 0) {
-				unicodeStoreAt(++this.withoutUnicodePtr);
+				unicodeStore();
 			}
 		}
 
@@ -3246,7 +3293,7 @@
 				getNextUnicodeChar();
 			} else {
 				if (this.withoutUnicodePtr != 0) {
-					unicodeStoreAt(++this.withoutUnicodePtr);
+					unicodeStore();
 				}
 			}
 		}
@@ -3324,7 +3371,6 @@
 		this.linePtr = lineSeparatorPositions.length - 1;
 	}
 }
-
 public String toString() {
 	if (this.startPosition == this.source.length)
 		return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
@@ -3570,6 +3616,8 @@
 			return "="; //$NON-NLS-1$
 		case TokenNameEOF :
 			return "EOF"; //$NON-NLS-1$
+		case TokenNameWHITESPACE :
+			return "white_space(" + new String(getCurrentTokenSource()) + ")"; //$NON-NLS-1$ //$NON-NLS-2$
 		default :
 			return "not-a-token"; //$NON-NLS-1$
 	}
@@ -3583,7 +3631,8 @@
     }
 	System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);    
 }
-public void unicodeStoreAt(int pos) {
+public void unicodeStore() {
+	int pos = ++this.withoutUnicodePtr;
     if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
     int length = this.withoutUnicodeBuffer.length;
     if (pos == length) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java
index 69fa248..d490044 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RecordedParsingInformation.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2002, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java
index 3fedd9c..b0c5a6b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ReferenceInfoAdapter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java
index 3644b28..e0bb58f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java
index def1d59..91cd147 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java
index a56d40d..5360535 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java
index ec17be2..9e4d5ab 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java
index b04b091..fa7612e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java
index 9996bc3..3362c19 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleDocument.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleSet.java
index d8fc095..fe7c065 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleSet.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -48,6 +48,12 @@
 	return object;
 }
 
+public void clear() {
+	for (int i = this.values.length; --i >= 0;)
+		this.values[i] = null;
+	this.elementSize = 0;
+}
+
 public Object clone() throws CloneNotSupportedException {
 	SimpleSet result = (SimpleSet) super.clone();
 	result.elementSize = this.elementSize;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java
index acaff10..306c5cc 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SimpleWordSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -65,4 +65,4 @@
 	this.elementSize = newSet.elementSize;
 	this.threshold = newSet.threshold;
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java
index 1aa89da..b0cadcd 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java
index a51c7d8..c20a83b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ToStringSorter.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
index dee5905..e1bb0aa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,8 +20,17 @@
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ArrayType;
+import org.eclipse.jdt.core.dom.ParameterizedType;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.QualifiedType;
+import org.eclipse.jdt.core.dom.SimpleType;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.WildcardType;
 import org.eclipse.jdt.core.util.IClassFileAttribute;
 import org.eclipse.jdt.core.util.IClassFileReader;
 import org.eclipse.jdt.core.util.ICodeAttribute;
@@ -62,20 +71,20 @@
 	}
 	private static final String ARGUMENTS_DELIMITER = "#"; //$NON-NLS-1$
 
-	/* Bundle containing messages */
-	protected static ResourceBundle bundle;
-	private final static String bundleName = "org.eclipse.jdt.internal.core.util.messages"; //$NON-NLS-1$
-
-	private final static char[] DOUBLE_QUOTES = "''".toCharArray(); //$NON-NLS-1$
 	private static final String EMPTY_ARGUMENT = "   "; //$NON-NLS-1$
 	
-	private final static char[] SINGLE_QUOTE = "'".toCharArray(); //$NON-NLS-1$
-	
-	public static char[][] JAVA_LIKE_EXTENSIONS = {SuffixConstants.SUFFIX_java, SuffixConstants.SUFFIX_JAVA};
+	private static char[][] JAVA_LIKE_EXTENSIONS;
 
-	static {
-		relocalize();
-	}	
+	private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
+	private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
+	private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
+	private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
+	private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
+	private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$
+	private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$
+	private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
+	private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+	private static final char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
 
 	private Util() {
 		// cannot be instantiated
@@ -131,98 +140,6 @@
 	}
 
 	/**
-	 * Lookup the message with the given ID in this catalog 
-	 */
-	public static String bind(String id) {
-		return bind(id, (String[])null);
-	}
-	
-	/**
-	 * Lookup the message with the given ID in this catalog and bind its
-	 * substitution locations with the given string.
-	 */
-	public static String bind(String id, String binding) {
-		return bind(id, new String[] {binding});
-	}
-	
-	/**
-	 * Lookup the message with the given ID in this catalog and bind its
-	 * substitution locations with the given strings.
-	 */
-	public static String bind(String id, String binding1, String binding2) {
-		return bind(id, new String[] {binding1, binding2});
-	}
-
-	/**
-	 * Lookup the message with the given ID in this catalog and bind its
-	 * substitution locations with the given string values.
-	 */
-	public static String bind(String id, String[] arguments) {
-		if (id == null)
-			return "No message available"; //$NON-NLS-1$
-		String message = null;
-		try {
-			message = bundle.getString(id);
-		} catch (MissingResourceException e) {
-			// If we got an exception looking for the message, fail gracefully by just returning
-			// the id we were looking for.  In most cases this is semi-informative so is not too bad.
-			return "Missing message: " + id + " in: " + bundleName; //$NON-NLS-2$ //$NON-NLS-1$
-		}
-		// for compatibility with MessageFormat which eliminates double quotes in original message
-		char[] messageWithNoDoubleQuotes =
-			CharOperation.replace(message.toCharArray(), DOUBLE_QUOTES, SINGLE_QUOTE);
-	
-		if (arguments == null) return new String(messageWithNoDoubleQuotes);
-	
-		int length = messageWithNoDoubleQuotes.length;
-		int start = 0;
-		int end = length;
-		StringBuffer output = null;
-		while (true) {
-			if ((end = CharOperation.indexOf('{', messageWithNoDoubleQuotes, start)) > -1) {
-				if (output == null) output = new StringBuffer(length+arguments.length*20);
-				output.append(messageWithNoDoubleQuotes, start, end - start);
-				if ((start = CharOperation.indexOf('}', messageWithNoDoubleQuotes, end + 1)) > -1) {
-					int index = -1;
-					String argId = new String(messageWithNoDoubleQuotes, end + 1, start - end - 1);
-					try {
-						index = Integer.parseInt(argId);
-						if (arguments[index] == null) {
-							output.append('{').append(argId).append('}'); // leave parameter in since no better arg '{0}'
-						} else {
-							output.append(arguments[index]);
-						}
-					} catch (NumberFormatException nfe) { // could be nested message ID {compiler.name}
-						boolean done = false;
-						if (!id.equals(argId)) {
-							String argMessage = null;
-							try {
-								argMessage = bundle.getString(argId);
-								output.append(argMessage);
-								done = true;
-							} catch (MissingResourceException e) {
-								// unable to bind argument, ignore (will leave argument in)
-							}
-						}
-						if (!done) output.append(messageWithNoDoubleQuotes, end + 1, start - end);
-					} catch (ArrayIndexOutOfBoundsException e) {
-						output.append("{missing " + Integer.toString(index) + "}"); //$NON-NLS-2$ //$NON-NLS-1$
-					}
-					start++;
-				} else {
-					output.append(messageWithNoDoubleQuotes, end, length);
-					break;
-				}
-			} else {
-				if (output == null) return new String(messageWithNoDoubleQuotes);
-				output.append(messageWithNoDoubleQuotes, start, length - start);
-				break;
-			}
-		}
-		return output.toString();
-	}
-
-	/**
 	 * Checks the type signature in String sig, 
 	 * starting at start and ending before end (end is not included).
 	 * Returns the index of the character immediately after the signature if valid,
@@ -465,8 +382,8 @@
 	/**
 	 * Converts a type signature from the IBinaryType representation to the DC representation.
 	 */
-	public static String convertTypeSignature(char[] sig) {
-		return new String(sig).replace('/', '.');
+	public static String convertTypeSignature(char[] sig, int start, int length) {
+		return new String(sig, start, length).replace('/', '.');
 	}
 	
 	/*
@@ -671,8 +588,9 @@
 				return false;
 			}
 		}
-		suffixes: for (int i = 0, length = JAVA_LIKE_EXTENSIONS.length; i < length; i++) {
-			char[] suffix = JAVA_LIKE_EXTENSIONS[i];
+		char[][] javaLikeExtensions = getJavaLikeExtensions();
+		suffixes: for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+			char[] suffix = javaLikeExtensions[i];
 			if (stringLength + suffix.length != fileNameLength) continue;
 			for (int j = stringLength; j < fileNameLength; j++) {
 				if (fileName.charAt(j) != suffix[j-stringLength]) 
@@ -717,11 +635,11 @@
 				if (c == 'L') {
 					i = CharOperation.indexOf(';', sig, i + 1) + 1;
 					Assert.isTrue(i != 0);
-					result[count++] = convertTypeSignature(CharOperation.subarray(sig, start, i));
+					result[count++] = convertTypeSignature(sig, start, i - start);
 					start = i;
 				} else {
 					++i;
-					result[count++] = convertTypeSignature(CharOperation.subarray(sig, start, i));
+					result[count++] = convertTypeSignature(sig, start, i - start);
 					start = i;
 				}
 		}
@@ -817,6 +735,42 @@
 		return null;
 	}
 	/**
+	 * Returns the registered Java like extensions.
+	 */
+	public static char[][] getJavaLikeExtensions() {
+		if (JAVA_LIKE_EXTENSIONS == null) {
+			// TODO (jerome) reenable once JDT UI supports other file extensions (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=71460)
+			if (true)
+				JAVA_LIKE_EXTENSIONS = new char[][] {SuffixConstants.SUFFIX_java};
+			else {
+				IContentType javaContentType = Platform.getContentTypeManager().getContentType(JavaModelManager.JAVA_SOURCE_CONTENT_TYPE);
+				String[] fileExtensions = javaContentType == null ? null : javaContentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
+				// note that file extensions contains "java" as it is defined in JDT Core's plugin.xml
+				int length = fileExtensions == null ? 0 : fileExtensions.length;
+				char[][] extensions = new char[length][];
+				SimpleWordSet knownExtensions = new SimpleWordSet(length); // used to ensure no duplicate extensions
+				extensions[0] = SuffixConstants.SUFFIX_java; // ensure that ".java" is first
+				knownExtensions.add(SuffixConstants.SUFFIX_java);
+				int index = 1;
+				for (int i = 0; i < length; i++) {
+					String fileExtension = fileExtensions[i];
+					int extensionLength = fileExtension.length() + 1;
+					char[] extension = new char[extensionLength];
+					extension[0] = '.';
+					fileExtension.getChars(0, extensionLength-1, extension, 1);
+					if (!knownExtensions.includes(extension)) {
+						extensions[index++] = extension;
+						knownExtensions.add(extension);
+					}
+				}
+				if (index != length)
+					System.arraycopy(extensions, 0, extensions = new char[index][], 0, index);
+				JAVA_LIKE_EXTENSIONS = extensions;
+			}
+		}
+		return JAVA_LIKE_EXTENSIONS;
+	}
+	/**
 	 * Get the jdk level of this root.
 	 * The value can be:
 	 * <ul>
@@ -879,6 +833,14 @@
 	}
 	
 	/**
+	 * Returns the substring of the given file name, ending at the start of a Java like extension.
+	 */
+	public static String getNameWithoutJavaLikeExtension(String fileName) {
+		int index = indexOfJavaLikeExtension(fileName);
+		return fileName.substring(0, index);
+	}
+	
+	/**
 	 * Returns the line separator used by the given buffer.
 	 * Uses the given text if none found.
 	 *
@@ -1045,7 +1007,68 @@
 			}
 		}
 	}
+/*
+	 * Returns the signature of the given type.
+	 */
+	public static String getSignature(Type type) {
+		StringBuffer buffer = new StringBuffer();
+		getFullyQualifiedName(type, buffer);
+		return Signature.createTypeSignature(buffer.toString(), false/*not resolved in source*/);
+	}
 	
+	/*
+	 * Appends to the given buffer the fully qualified name (as it appears in the source) of the given type
+	 */
+	private static void getFullyQualifiedName(Type type, StringBuffer buffer) {
+		switch (type.getNodeType()) {
+			case ASTNode.ARRAY_TYPE:
+				ArrayType arrayType = (ArrayType) type;
+				getFullyQualifiedName(arrayType.getElementType(), buffer);
+				for (int i = 0, length = arrayType.getDimensions(); i < length; i++) {
+					buffer.append('[');
+					buffer.append(']');
+				}
+				break;
+			case ASTNode.PARAMETERIZED_TYPE:
+				ParameterizedType parameterizedType = (ParameterizedType) type;
+				getFullyQualifiedName(parameterizedType.getType(), buffer);
+				buffer.append('<');
+				Iterator iterator = parameterizedType.typeArguments().iterator();
+				boolean isFirst = true;
+				while (iterator.hasNext()) {
+					if (!isFirst)
+						buffer.append(',');
+					else
+						isFirst = false;
+					Type typeArgument = (Type) iterator.next();
+					getFullyQualifiedName(typeArgument, buffer);
+				}
+				buffer.append('>');
+				break;
+			case ASTNode.PRIMITIVE_TYPE:
+				buffer.append(((PrimitiveType) type).getPrimitiveTypeCode().toString());
+				break;
+			case ASTNode.QUALIFIED_TYPE:
+				buffer.append(((QualifiedType) type).getName().getFullyQualifiedName());
+				break;
+			case ASTNode.SIMPLE_TYPE:
+				buffer.append(((SimpleType) type).getName().getFullyQualifiedName());
+				break;
+			case ASTNode.WILDCARD_TYPE:
+				buffer.append('?');
+				WildcardType wildcardType = (WildcardType) type;
+				Type bound = wildcardType.getBound();
+				if (bound == null) return;
+				if (wildcardType.isUpperBound()) {
+					buffer.append(" extends "); //$NON-NLS-1$
+				} else {
+					buffer.append(" super "); //$NON-NLS-1$
+				}
+				getFullyQualifiedName(bound, buffer);
+				break;
+		}
+	}
+
 	/**
 	 * Returns a trimmed version the simples names returned by Signature.
 	 */
@@ -1082,8 +1105,9 @@
 	 */
 	public static int indexOfJavaLikeExtension(String fileName) {
 		int fileNameLength = fileName.length();
-		extensions: for (int i = 0, length = JAVA_LIKE_EXTENSIONS.length; i < length; i++) {
-			char[] extension = JAVA_LIKE_EXTENSIONS[i];
+		char[][] javaLikeExtensions = getJavaLikeExtensions();
+		extensions: for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+			char[] extension = javaLikeExtensions[i];
 			int extensionLength = extension.length;
 			int extensionStart = fileNameLength - extensionLength;
 			if (extensionStart < 0) continue;
@@ -1665,16 +1689,47 @@
 	}
 
 	/**
-	 * Creates a NLS catalog for the given locale.
+	 * Returns the toString() of the given full path minus the first given number of segments.
+	 * The returned string is always a relative path (it has no leading slash)
 	 */
-	public static void relocalize() {
-		try {
-			bundle = ResourceBundle.getBundle(bundleName, Locale.getDefault());
-		} catch(MissingResourceException e) {
-			System.out.println("Missing resource : " + bundleName.replace('.', '/') + ".properties for locale " + Locale.getDefault()); //$NON-NLS-1$//$NON-NLS-2$
-			throw e;
+	public static String relativePath(IPath fullPath, int skipSegmentCount) {
+		boolean hasTrailingSeparator = fullPath.hasTrailingSeparator();
+		String[] segments = fullPath.segments();
+		
+		// compute length
+		int length = 0;
+		int max = segments.length;
+		if (max > skipSegmentCount) {
+			for (int i1 = skipSegmentCount; i1 < max; i1++) {
+				length += segments[i1].length();
+			}
+			//add the separator lengths
+			length += max - skipSegmentCount - 1;
 		}
+		if (hasTrailingSeparator)
+			length++;
+
+		char[] result = new char[length];
+		int offset = 0;
+		int len = segments.length - 1;
+		if (len >= skipSegmentCount) {
+			//append all but the last segment, with separators
+			for (int i = skipSegmentCount; i < len; i++) {
+				int size = segments[i].length();
+				segments[i].getChars(0, size, result, offset);
+				offset += size;
+				result[offset++] = '/';
+			}
+			//append the last segment
+			int size = segments[len].length();
+			segments[len].getChars(0, size, result, offset);
+			offset += size;
+		}
+		if (hasTrailingSeparator)
+			result[offset++] = '/';
+		return new String(result);
 	}
+	
 	/**
 	 * Return a new array which is the split of the given string using the given divider. The given end 
 	 * is exclusive and the given start is inclusive.
@@ -1911,6 +1966,157 @@
 	}
 	
 	/*
+	 * Converts a char[][] to String[].
+	 */
+	public static String[] toStrings(char[][] a) {
+		int len = a.length;
+		String[] result = new String[len];
+		for (int i = 0; i < len; ++i) {
+			result[i] = new String(a[i]);
+		}
+		return result;
+	}
+	private static void appendArrayTypeSignature(char[] string, int start, StringBuffer buffer) {
+		// need a minimum 2 char
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_ARRAY) { //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		}
+		appendTypeSignature(string, start + 1, buffer);
+		buffer.append('[').append(']');
+	}
+	private static void appendClassTypeSignature(char[] string, int start, StringBuffer buffer) {
+		char c = string[start];
+		if (c != Signature.C_RESOLVED) {
+			return;
+		}
+		int p = start + 1;
+		int checkpoint = buffer.length();
+		while (true) {
+			c = string[p];
+			switch(c) {
+				case Signature.C_SEMICOLON :
+					// all done
+					return;
+				case Signature.C_DOT :
+					// erase package prefix
+					buffer.setLength(checkpoint);
+					break;
+				 case '/' :
+					// erase package prefix
+					buffer.setLength(checkpoint);
+					break;
+				 case Signature.C_DOLLAR :
+					/**
+					 * Convert '$' in resolved type signatures into '.'.
+					 * NOTE: This assumes that the type signature is an inner type
+					 * signature. This is true in most cases, but someone can define a
+					 * non-inner type name containing a '$'.
+					 */
+					buffer.append('.');
+				 	break;
+				 default :
+					buffer.append(c);
+			}
+			p++;
+		}
+	}
+	static void appendTypeSignature(char[] string, int start, StringBuffer buffer) {
+		char c = string[start];
+		switch (c) {
+			case Signature.C_ARRAY :
+				appendArrayTypeSignature(string, start, buffer);
+				break;
+			case Signature.C_RESOLVED :
+				appendClassTypeSignature(string, start, buffer);
+				break;
+			case Signature.C_TYPE_VARIABLE :
+				int e = Util.scanTypeVariableSignature(string, start);
+				buffer.append(string, start + 1, e - start - 1);
+				break;
+			case Signature.C_BOOLEAN :
+				buffer.append(BOOLEAN);
+				break;
+			case Signature.C_BYTE :
+				buffer.append(BYTE);
+				break;
+			case Signature.C_CHAR :
+				buffer.append(CHAR);
+				break;
+			case Signature.C_DOUBLE :
+				buffer.append(DOUBLE);
+				break;
+			case Signature.C_FLOAT :
+				buffer.append(FLOAT);
+				break;
+			case Signature.C_INT :
+				buffer.append(INT);
+				break;
+			case Signature.C_LONG :
+				buffer.append(LONG);
+				break;
+			case Signature.C_SHORT :
+				buffer.append(SHORT);
+				break;
+			case Signature.C_VOID :
+				buffer.append(VOID);
+				break;
+		}
+	}
+	public static String toString(char[] declaringClass, char[] methodName, char[] methodSignature, boolean includeReturnType) {
+		boolean isConstructor = CharOperation.equals(methodName, INIT);
+		int firstParen = CharOperation.indexOf(Signature.C_PARAM_START, methodSignature);
+		if (firstParen == -1) {
+			return ""; //$NON-NLS-1$
+		}
+		
+		StringBuffer buffer = new StringBuffer(methodSignature.length + 10);
+		
+		if (!isConstructor) {
+			// return type
+			if (includeReturnType) {
+				char[] rts = Signature.getReturnType(methodSignature);
+				appendTypeSignature(rts, 0 , buffer);
+				buffer.append(' ');
+			}
+		}
+		
+		// selector
+		int lastIndexOfSlash = CharOperation.lastIndexOf('/', declaringClass);
+		if (lastIndexOfSlash != -1) {
+			buffer.append(declaringClass, lastIndexOfSlash + 1, declaringClass.length - lastIndexOfSlash - 1);
+		} else {
+			buffer.append(declaringClass);
+		}
+		if (!isConstructor) {
+			buffer.append('.');
+	
+			if (methodName != null) {
+				buffer.append(methodName);
+			}
+		}
+		
+		// parameters
+		buffer.append('(');
+		char[][] pts = Signature.getParameterTypes(methodSignature);
+		for (int i = 0, max = pts.length; i < max; i++) {
+			if (i == max - 1) {
+				appendTypeSignature(pts[i], 0 , buffer);
+			} else {
+				appendTypeSignature(pts[i], 0 , buffer);
+			}
+			if (i != pts.length - 1) {
+				buffer.append(',');
+				buffer.append(' ');
+			}
+		}
+		buffer.append(')');
+		return String.valueOf(buffer);
+	}
+	/*
 	 * Returns the unresolved type parameter signatures of the given method
 	 * e.g. {"QString;", "[int", "[[Qjava.util.Vector;"}
 	 */
@@ -2036,8 +2242,9 @@
 	public final static boolean isJavaLikeFileName(char[] fileName) {
 		if (fileName == null) return false;
 		int fileNameLength = fileName.length;
-		extensions: for (int i = 0, length = JAVA_LIKE_EXTENSIONS.length; i < length; i++) {
-			char[] extension = JAVA_LIKE_EXTENSIONS[i];
+		char[][] javaLikeExtensions = getJavaLikeExtensions();
+		extensions: for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+			char[] extension = javaLikeExtensions[i];
 			int extensionLength = extension.length;
 			int extensionStart = fileNameLength - extensionLength;
 			if (extensionStart < 0) continue;
@@ -2048,5 +2255,483 @@
 			return true;
 		}
 		return false;
+	}
+
+	/**
+	 * Scans the given string for a type signature starting at the given index
+	 * and returns the index of the last character.
+	 * <pre>
+	 * TypeSignature:
+	 *  |  BaseTypeSignature
+	 *  |  ArrayTypeSignature
+	 *  |  ClassTypeSignature
+	 *  |  TypeVariableSignature
+	 * </pre>
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type signature
+	 */
+	public static int scanTypeSignature(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch (c) {
+			case Signature.C_ARRAY :
+				return scanArrayTypeSignature(string, start);
+			case Signature.C_RESOLVED :
+			case Signature.C_UNRESOLVED :
+				return scanClassTypeSignature(string, start);
+			case Signature.C_TYPE_VARIABLE :
+				return scanTypeVariableSignature(string, start);
+			case Signature.C_BOOLEAN :
+			case Signature.C_BYTE :
+			case Signature.C_CHAR :
+			case Signature.C_DOUBLE :
+			case Signature.C_FLOAT :
+			case Signature.C_INT :
+			case Signature.C_LONG :
+			case Signature.C_SHORT :
+			case Signature.C_VOID :
+				return scanBaseTypeSignature(string, start);
+			case Signature.C_CAPTURE :
+				return scanCaptureTypeSignature(string, start);
+			case Signature.C_EXTENDS:
+			case Signature.C_SUPER:
+			case Signature.C_STAR:
+				return scanTypeBoundSignature(string, start);
+			default :
+				throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for a base type signature starting at the given index
+	 * and returns the index of the last character.
+	 * <pre>
+	 * BaseTypeSignature:
+	 *     <b>B</b> | <b>C</b> | <b>D</b> | <b>F</b> | <b>I</b>
+	 *   | <b>J</b> | <b>S</b> | <b>V</b> | <b>Z</b>
+	 * </pre>
+	 * Note that although the base type "V" is only allowed in method return types,
+	 * there is no syntactic ambiguity. This method will accept them anywhere
+	 * without complaint.
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a base type signature
+	 */
+	public static int scanBaseTypeSignature(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if ("BCDFIJSVZ".indexOf(c) >= 0) { //$NON-NLS-1$
+			return start;
+		} else {
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for an array type signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * ArrayTypeSignature:
+	 *     <b>[</b> TypeSignature
+	 * </pre>
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not an array type signature
+	 */
+	public static int scanArrayTypeSignature(char[] string, int start) {
+		// need a minimum 2 char
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_ARRAY) { //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		}
+		return scanTypeSignature(string, start + 1);
+	}
+	
+	/**
+	 * Scans the given string for a capture of a wildcard type signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * CaptureTypeSignature:
+	 *     <b>!</b> TypeBoundSignature
+	 * </pre>
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a capture type signature
+	 */
+	public static int scanCaptureTypeSignature(char[] string, int start) {
+		// need a minimum 2 char
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_CAPTURE) { //$NON-NLS-1$
+			throw new IllegalArgumentException();
+		}
+		return scanTypeBoundSignature(string, start + 1);
 	}	
+
+	/**
+	 * Scans the given string for a type variable signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * TypeVariableSignature:
+	 *     <b>T</b> Identifier <b>;</b>
+	 * </pre>
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type variable signature
+	 */
+	public static int scanTypeVariableSignature(char[] string, int start) {
+		// need a minimum 3 chars "Tx;"
+		if (start >= string.length - 2) { 
+			throw new IllegalArgumentException();
+		}
+		// must start in "T"
+		char c = string[start];
+		if (c != Signature.C_TYPE_VARIABLE) {
+			throw new IllegalArgumentException();
+		}
+		int id = scanIdentifier(string, start + 1);
+		c = string[id + 1];
+		if (c == Signature.C_SEMICOLON) {
+			return id + 1;
+		} else {
+			throw new IllegalArgumentException();
+		}
+	}
+
+	/**
+	 * Scans the given string for an identifier starting at the given
+	 * index and returns the index of the last character. 
+	 * Stop characters are: ";", ":", "&lt;", "&gt;", "/", ".".
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not an identifier
+	 */
+	public static int scanIdentifier(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) { 
+			throw new IllegalArgumentException();
+		}
+		int p = start;
+		while (true) {
+			char c = string[p];
+			if (c == '<' || c == '>' || c == ':' || c == ';' || c == '.' || c == '/') {
+				return p - 1;
+			}
+			p++;
+			if (p == string.length) {
+				return p - 1;
+			}
+		}
+	}
+
+	/**
+	 * Scans the given string for a class type signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * ClassTypeSignature:
+	 *     { <b>L</b> | <b>Q</b> } Identifier
+	 *           { { <b>/</b> | <b>.</b> Identifier [ <b>&lt;</b> TypeArgumentSignature* <b>&gt;</b> ] }
+	 *           <b>;</b>
+	 * </pre>
+	 * Note that although all "/"-identifiers most come before "."-identifiers,
+	 * there is no syntactic ambiguity. This method will accept them without
+	 * complaint.
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a class type signature
+	 */
+	public static int scanClassTypeSignature(char[] string, int start) {
+		// need a minimum 3 chars "Lx;"
+		if (start >= string.length - 2) { 
+			throw new IllegalArgumentException();
+		}
+		// must start in "L" or "Q"
+		char c = string[start];
+		if (c != Signature.C_RESOLVED && c != Signature.C_UNRESOLVED) {
+			return -1;
+		}
+		int p = start + 1;
+		while (true) {
+			if (p >= string.length) {
+				throw new IllegalArgumentException();
+			}
+			c = string[p];
+			if (c == Signature.C_SEMICOLON) {
+				// all done
+				return p;
+			} else if (c == Signature.C_GENERIC_START) {
+				int e = scanTypeArgumentSignatures(string, p);
+				p = e;
+			} else if (c == Signature.C_DOT || c == '/') {
+				int id = scanIdentifier(string, p + 1);
+				p = id;
+			}
+			p++;
+		}
+	}
+
+	/**
+	 * Scans the given string for a type bound signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * TypeBoundSignature:
+	 *     <b>[-+]</b> TypeSignature <b>;</b>
+	 *     <b>*</b></b>
+	 * </pre>
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type variable signature
+	 */
+	public static int scanTypeBoundSignature(char[] string, int start) {
+		// need a minimum 1 char for wildcard
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch (c) {
+			case Signature.C_STAR :
+				return start;
+			case Signature.C_SUPER :
+			case Signature.C_EXTENDS :
+				// need a minimum 4 chars "+Lx;"
+				if (start >= string.length - 3) {
+					throw new IllegalArgumentException();
+				}
+				break;
+			default :
+				// must start in "+/-"
+					throw new IllegalArgumentException();
+				
+		}
+		c = string[++start];
+		switch (c) {
+			case Signature.C_CAPTURE :
+				return scanCaptureTypeSignature(string, start);
+			case Signature.C_SUPER :
+			case Signature.C_EXTENDS :
+				return scanTypeBoundSignature(string, start);
+			case Signature.C_RESOLVED :
+			case Signature.C_UNRESOLVED :
+				return scanClassTypeSignature(string, start);
+			case Signature.C_TYPE_VARIABLE :
+				return scanTypeVariableSignature(string, start);
+			case Signature.C_ARRAY :
+				return scanArrayTypeSignature(string, start);
+			default:
+				throw new IllegalArgumentException();
+		}
+	}
+	
+	/**
+	 * Scans the given string for a list of type argument signatures starting at
+	 * the given index and returns the index of the last character.
+	 * <pre>
+	 * TypeArgumentSignatures:
+	 *     <b>&lt;</b> TypeArgumentSignature* <b>&gt;</b>
+	 * </pre>
+	 * Note that although there is supposed to be at least one type argument, there
+	 * is no syntactic ambiguity if there are none. This method will accept zero
+	 * type argument signatures without complaint.
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a list of type arguments
+	 * signatures
+	 */
+	public static int scanTypeArgumentSignatures(char[] string, int start) {
+		// need a minimum 2 char "<>"
+		if (start >= string.length - 1) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		if (c != Signature.C_GENERIC_START) {
+			throw new IllegalArgumentException();
+		}
+		int p = start + 1;
+		while (true) {
+			if (p >= string.length) {
+				throw new IllegalArgumentException();
+			}
+			c = string[p];
+			if (c == Signature.C_GENERIC_END) {
+				return p;
+			}
+			int e = scanTypeArgumentSignature(string, p);
+			p = e + 1;
+		}
+	}
+
+	/**
+	 * Scans the given string for a type argument signature starting at the given
+	 * index and returns the index of the last character.
+	 * <pre>
+	 * TypeArgumentSignature:
+	 *     <b>&#42;</b>
+	 *  |  <b>+</b> TypeSignature
+	 *  |  <b>-</b> TypeSignature
+	 *  |  TypeSignature
+	 * </pre>
+	 * Note that although base types are not allowed in type arguments, there is
+	 * no syntactic ambiguity. This method will accept them without complaint.
+	 * 
+	 * @param string the signature string
+	 * @param start the 0-based character index of the first character
+	 * @return the 0-based character index of the last character
+	 * @exception IllegalArgumentException if this is not a type argument signature
+	 */
+	public static int scanTypeArgumentSignature(char[] string, int start) {
+		// need a minimum 1 char
+		if (start >= string.length) {
+			throw new IllegalArgumentException();
+		}
+		char c = string[start];
+		switch (c) {
+			case Signature.C_STAR :
+				return start;
+			case Signature.C_EXTENDS :
+			case Signature.C_SUPER :
+				return scanTypeBoundSignature(string, start);
+			default :
+				return scanTypeSignature(string, start);
+		}
+	}	
+
+	/**
+	 * Get all type arguments from an array of signatures.
+	 * 
+	 * Example:
+	 * 	For following type X<Y<Z>,V<W>,U>.A<B> signatures is:
+	 * 	[
+	 * 		['L','X','<','L','Y','<','L','Z',';'>',';','L','V','<','L','W',';'>',';','L','U',';',>',';'],
+	 * 		['L','A','<','L','B',';','>',';']
+	 * 	]
+	 * 	@see #splitTypeLevelsSignature(String)
+	 * 	Then, this method returns:
+	 * 	[
+	 * 		[
+	 * 			['L','Y','<','L','Z',';'>',';'],
+	 * 			['L','V','<','L','W',';'>',';'],
+	 * 			['L','U',';']
+	 * 		],
+	 * 		[
+	 * 			['L','B',';']
+	 * 		]
+	 * 	]
+	 * 
+	 * @param typeSignatures Array of signatures (one per each type levels)
+	 * @throws IllegalArgumentException If one of provided signature is malformed
+	 * @return char[][][] Array of type arguments for each signature
+	 */
+	public final static char[][][] getAllTypeArguments(char[][] typeSignatures) {
+		if (typeSignatures == null) return null;
+		int length = typeSignatures.length;
+		char[][][] typeArguments = new char[length][][];
+		for (int i=0; i<length; i++){
+			typeArguments[i] = Signature.getTypeArguments(typeSignatures[i]);
+		}
+		return typeArguments;
+	}
+	/**
+	 * Split signatures of all levels  from a type unique key.
+	 * 
+	 * Example:
+	 * 	For following type X<Y<Z>,V<W>,U>.A<B>, unique key is:
+	 * 	"LX<LY<LZ;>;LV<LW;>;LU;>.LA<LB;>;"
+	 * 
+	 * 	The return splitted signatures array is:
+	 * 	[
+	 * 		['L','X','<','L','Y','<','L','Z',';'>',';','L','V','<','L','W',';'>',';','L','U','>',';'],
+	 * 		['L','A','<','L','B',';','>',';']
+	 * 
+	 * @param typeSignature ParameterizedSourceType type signature
+	 * @return char[][] Array of signatures for each level of given unique key
+	 */
+	public final static char[][] splitTypeLevelsSignature(String typeSignature) {
+		// In case of IJavaElement signature, replace '$' by '.'
+		char[] source = Signature.removeCaptureFromMethod(typeSignature.toCharArray());
+		CharOperation.replace(source, '$', '.');
+
+		// Init counters and arrays
+		char[][] signatures = new char[10][];
+		int signaturesCount = 0;
+//		int[] lengthes = new int [10];
+		int typeArgsCount = 0;
+		int paramOpening = 0;
+		
+		// Scan each signature character
+		scanUniqueKey: for (int idx=0, ln = source.length; idx < ln; idx++) {
+			switch (source[idx]) {
+				case '>':
+					paramOpening--;
+					if (paramOpening == 0)  {
+						if (signaturesCount == signatures.length) {
+							System.arraycopy(signatures, 0, signatures = new char[signaturesCount+10][], 0, signaturesCount);
+						}
+						typeArgsCount = 0;
+					}
+					break;
+				case '<':
+					paramOpening++;
+					if (paramOpening == 1) {
+						typeArgsCount = 1;
+					}
+					break;
+				case '*':
+				case ';':
+					if (paramOpening == 1) typeArgsCount++;
+					break;
+				case '.':
+					if (paramOpening == 0)  {
+						if (signaturesCount == signatures.length) {
+							System.arraycopy(signatures, 0, signatures = new char[signaturesCount+10][], 0, signaturesCount);
+						}
+						signatures[signaturesCount] = new char[idx+1];
+						System.arraycopy(source, 0, signatures[signaturesCount], 0, idx);
+						signatures[signaturesCount][idx] = Signature.C_SEMICOLON;
+						signaturesCount++;
+					}
+					break;
+				case '/':
+					source[idx] = '.';
+					break;
+			}
+		}
+
+		// Resize signatures array
+		char[][] typeSignatures = new char[signaturesCount+1][];
+		typeSignatures[0] = source;
+		for (int i=1, j=signaturesCount-1; i<=signaturesCount; i++, j--){
+			typeSignatures[i] = signatures[j];
+		}
+		return typeSignatures;
+	}
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
index 1de606f..ea0d966 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -1,10 +1,10 @@
 ###############################################################################
-# Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
@@ -12,335 +12,332 @@
 ### JavaModel messages.
 
 ### hierarchy
-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}...
+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.notOnClasspath = {0} is not on its project's build path
-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.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
-sourcetype.invalidName = The source type has an invalid name: {0}
+element_doesNotExist = {0} does not exist
+element_notOnClasspath = {0} is not on its project''s build path
+element_invalidClassFileName = Class file name must end with .class
+element_reconciling = Reconciling...
+element_attachingSource = Attaching source...
+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
+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.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.copyElementProgress = Copying elements...
-operation.moveElementProgress = Moving elements...
-operation.renameElementProgress = Renaming elements...
-operation.copyResourceProgress = Copying resources...
-operation.moveResourceProgress = Moving resources...
-operation.renameResourceProgress = Renaming resources...
-operation.createUnitProgress = Creating a compilation unit...
-operation.createFieldProgress = Creating a field...
-operation.createImportsProgress = Creating imports...
-operation.createInitializerProgress = Creating an initializer...
-operation.createMethodProgress = Creating a method...
-operation.createPackageProgress = Creating a package declaration...
-operation.createPackageFragmentProgress = Creating package fragment(s)...
-operation.createTypeProgress = Creating a type...
-operation.deleteElementProgress = Deleting elements...
-operation.deleteResourceProgress = Deleting resources...
-operation.cannotRenameDefaultPackage = Default package cannot be renamed
-operation.pathOutsideProject = Path ''{0}'' must denote location inside project {1}
-operation.sortelements = Sorting elements...
+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_copyElementProgress = Copying elements...
+operation_moveElementProgress = Moving elements...
+operation_renameElementProgress = Renaming elements...
+operation_copyResourceProgress = Copying resources...
+operation_moveResourceProgress = Moving resources...
+operation_renameResourceProgress = Renaming resources...
+operation_createUnitProgress = Creating a compilation unit...
+operation_createFieldProgress = Creating a field...
+operation_createImportsProgress = Creating imports...
+operation_createInitializerProgress = Creating an initializer...
+operation_createMethodProgress = Creating a method...
+operation_createPackageProgress = Creating a package declaration...
+operation_createPackageFragmentProgress = Creating package fragment(s)...
+operation_createTypeProgress = Creating a type...
+operation_deleteElementProgress = Deleting elements...
+operation_deleteResourceProgress = Deleting resources...
+operation_cannotRenameDefaultPackage = Default package cannot be renamed
+operation_pathOutsideProject = Path ''{0}'' must denote location inside project {1}
+operation_sortelements = Sorting elements...
 
 ### working copy
-workingCopy.commit = Committing working copy...
+workingCopy_commit = Committing working copy...
 
 ### build status messages
-build.preparingBuild = Preparing for build
-build.readStateProgress = Reading saved built state for project {0}
-build.saveStateProgress = Saving built state for project {0}
-build.saveStateComplete = Saved in {0} ms
-build.readingDelta = Reading resource change information for {0}
-build.analyzingDeltas = Analyzing deltas
-build.analyzingSources = Analyzing sources
-build.cleaningOutput = Cleaning output folder
-build.copyingResources = Copying resources to the output folder
-build.compiling = Compiling {0}
-build.foundHeader = Found
-build.fixedHeader = Fixed
-build.oneError = 1 error
-build.oneWarning = 1 warning
-build.multipleErrors = {0} errors
-build.multipleWarnings = {0} warnings
-build.done = Build done
+build_preparingBuild = Preparing for build
+build_readStateProgress = Reading saved built state for project {0}
+build_saveStateProgress = Saving built state for project {0}
+build_saveStateComplete = Saved in {0} ms
+build_readingDelta = Reading resource change information for {0}
+build_analyzingDeltas = Analyzing deltas
+build_analyzingSources = Analyzing sources
+build_cleaningOutput = Cleaning output folder
+build_copyingResources = Copying resources to the output folder
+build_compiling = Compiling {0}
+build_foundHeader = Found
+build_fixedHeader = Fixed
+build_oneError = 1 error
+build_oneWarning = 1 warning
+build_multipleErrors = {0} errors
+build_multipleWarnings = {0} warnings
+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.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_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_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
 
 ### 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.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.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.illegalEntryInClasspathFile = Illegal entry in ''.classpath'' of project {0} file: {1}
-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.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.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_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_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_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_illegalEntryInClasspathFile = Illegal entry in ''.classpath'' of project {0} file: {1}
+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_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_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
 
 ### miscellaneous
-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
+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
 
 ### access restrictions
-restrictedAccess.project = The type {0} is not imported from required project {1}  
-restrictedAccess.library = The type {0} is not imported from required library {1}
+restrictedAccess_project = The type {0} is not accessible due to restriction on required project {1}
+restrictedAccess_library = The type {0} is not accessible due to restriction on required library {1}
 
 ### 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.compiler.invalidCompilerOption = ''{0}'' is not valid value for ''{1}'' compiler option.
-convention.compiler.incompatibleTargetForSource = Target level ''{0}'' is incompatible with source level ''{1}''. A target level ''{1}'' or better is required
-convention.compiler.incompatibleComplianceForSource = Compliance level ''{0}'' is incompatible with source level ''{1}''. A compliance level ''{1}'' or better is required
-convention.compiler.incompatibleComplianceForTarget = Compliance level ''{0}'' is incompatible with target level ''{1}''. A compliance level ''{1}'' or better is required
+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.nullTypeParameter = Cannot add parameter with null type
-dom.nullNameParameter = Cannot add parameter with null name
-dom.nullReturnType = Return type cannot be null
-dom.nullExceptionType = Cannot add null exception
-dom.mismatchArgNamesAndTypes = Types and names must have identical length
-dom.addNullChild = Attempt to add null child
-dom.addIncompatibleChild = Attempt to add child of incompatible type
-dom.addChildWithParent = Attempt to add child that is already parented
-dom.unableAddChild = Attempt to add child to node that cannot have children
-dom.addAncestorAsChild = Attempt to add ancestor as child
-dom.addNullSibling = Attempt to insert null sibling
-dom.addSiblingBeforeRoot = Attempt to insert sibling before root node
-dom.addIncompatibleSibling = Attempt to insert sibling of incompatible type
-dom.addSiblingWithParent = Attempt to insert sibling that is already parented
-dom.addAncestorAsSibling = Attempt to insert ancestor as sibling
-dom.addNullInterface = Cannot add null interface
-dom.nullInterfaces = Illegal to set super interfaces to null
+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
+dom_nullExceptionType = Cannot add null exception
+dom_mismatchArgNamesAndTypes = Types and names must have identical length
+dom_addNullChild = Attempt to add null child
+dom_addIncompatibleChild = Attempt to add child of incompatible type
+dom_addChildWithParent = Attempt to add child that is already parented
+dom_unableAddChild = Attempt to add child to node that cannot have children
+dom_addAncestorAsChild = Attempt to add ancestor as child
+dom_addNullSibling = Attempt to insert null sibling
+dom_addSiblingBeforeRoot = Attempt to insert sibling before root node
+dom_addIncompatibleSibling = Attempt to insert sibling of incompatible type
+dom_addSiblingWithParent = Attempt to insert sibling that is already parented
+dom_addAncestorAsSibling = Attempt to insert ancestor as sibling
+dom_addNullInterface = Cannot add null interface
+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.
 
-engine.searching = Searching...
-engine.searching.indexing = {0}: lookup indexes...
-engine.searching.matching = {0}: locate matches...
-exception.wrongFormat = Wrong format
-process.name = Java indexing
-manager.filesToIndex = {0} files to index
-manager.indexingInProgress = Java indexing in progress
+engine_searching = Searching...
+engine_searching_indexing = {0}: lookup indexes...
+engine_searching_matching = {0}: locate matches...
+exception_wrongFormat = Wrong format
+process_name = Java indexing
+manager_filesToIndex = {0} files to index
+manager_indexingInProgress = Java indexing in progress
 
 ### Disassembler messages
 
 ### disassembler
-disassembler.description = Default classfile disassembler
-disassembler.opentypedeclaration =\ {
-disassembler.closetypedeclaration = }
-disassembler.parametername = arg
-disassembler.endofmethodheader = ;
-disassembler.begincommentline = //\ 
-disassembler.fieldhasconstant =\ =\ 
-disassembler.endoffieldheader = ;
-disassembler.sourceattributeheader = Compiled from 
-disassembler.enclosingmethodheader = Enclosing Method:
-disassembler.exceptiontableheader = Exception Table:
-disassembler.linenumberattributeheader = Line numbers:
-disassembler.localvariabletableattributeheader = Local variable table:
-disassembler.localvariabletypetableattributeheader = Local variable type table:
-disassembler.arraydimensions = []
-disassembler.innerattributesheader = Inner classes:
-disassembler.inner_class_info_name = inner class info:
-disassembler.outer_class_info_name = outer class info:
-disassembler.inner_name = inner name:
-disassembler.inner_accessflags = accessflags: 
-disassembler.genericattributeheader = Attribute:\ 
-disassembler.genericattributename = Name: 
-disassembler.genericattributelength =\ Length: 
-disassembler.signatureattributeheader = Signature:\ 
-disassembler.indentation = \  
-disassembler.constantpoolindex =\ #
-disassembler.classmemberseparator = .
-disassembler.space = \ 
-disassembler.comma = ,
-disassembler.openinnerclassentry = [
-disassembler.closeinnerclassentry = ]
-disassembler.deprecated =\ (deprecated)
-disassembler.constantpoolheader = Constant pool:
-disassembler.constantpool.class = constant #{0} class: #{1} {2}
-disassembler.constantpool.double = constant #{0} double: {1}
-disassembler.constantpool.float = constant #{0} float: {1}
-disassembler.constantpool.integer = constant #{0} integer: {1}
-disassembler.constantpool.long = constant #{0} long: {1}
-disassembler.constantpool.string = constant #{0} string: #{1} {2}
-disassembler.constantpool.fieldref = constant #{0} field_ref: #{1}.#{2} {3}.{4}
-disassembler.constantpool.interfacemethodref = constant #{0} interface_method_ref: #{1}.#{2} {3}.{4}
-disassembler.constantpool.methodref = constant #{0} method_ref: #{1}.#{2} {3}.{4}
-disassembler.constantpool.name_and_type = constant #{0} name_and_type: #{1}.#{2} {3} {4}
-disassembler.constantpool.utf8 = constant #{0} utf8: {1}
-disassembler.annotationdefaultheader = Annotation Default:\ 
-disassembler.annotationdefaultvalue= {0} (constant type)
-disassembler.annotationenumvalue = {2}.{3}(enum type #{0}.#{1})
-disassembler.annotationclassvalue = {1} (#{0} class type)
-disassembler.annotationannotationvalue = annotation value = 
-disassembler.annotationarrayvaluestart = [
-disassembler.annotationarrayvalueend = ]
-disassembler.annotationentrystart = #{0} @{1}(
-disassembler.annotationentryend = )
-disassembler.annotationcomponent = #{0} {1}=
-disassembler.runtimevisibleannotationsattributeheader= RuntimeVisibleAnnotations:\ 
-disassembler.runtimeinvisibleannotationsattributeheader= RuntimeInvisibleAnnotations:\ 
-disassembler.runtimevisibleparameterannotationsattributeheader= RuntimeVisibleParameterAnnotations:\ 
-disassembler.runtimeinvisibleparameterannotationsattributeheader= RuntimeInvisibleParameterAnnotations:\ 
-disassembler.parameterannotationentrystart=Number of annotations for parameter {0}: {1}
+disassembler_description = Default classfile disassembler
+disassembler_opentypedeclaration =\ '{'
+disassembler_closetypedeclaration = }
+disassembler_parametername = arg
+disassembler_localvariablename = local_{0}
+disassembler_endofmethodheader = ;
+disassembler_begincommentline = //\ 
+disassembler_fieldhasconstant =\ =\ 
+disassembler_endoffieldheader = ;
+disassembler_sourceattributeheader = Compiled from\ 
+disassembler_enclosingmethodheader = Enclosing Method:
+disassembler_exceptiontableheader = Exception Table:
+disassembler_linenumberattributeheader = Line numbers:
+disassembler_localvariabletableattributeheader = Local variable table:
+disassembler_localvariabletypetableattributeheader = Local variable type table:
+disassembler_arraydimensions = []
+disassembler_innerattributesheader = Inner classes:
+disassembler_inner_class_info_name = inner class info:
+disassembler_outer_class_info_name = outer class info:
+disassembler_inner_name = inner name:
+disassembler_inner_accessflags = accessflags:\ 
+disassembler_genericattributeheader = Attribute: Name: {0} Length: {1}
+disassembler_signatureattributeheader = // Signature: {0}
+disassembler_indentation = \  
+disassembler_constantpoolindex =\ #
+disassembler_space = \ 
+disassembler_comma = ,
+disassembler_openinnerclassentry = [
+disassembler_closeinnerclassentry = ]
+disassembler_deprecated =\ (deprecated)
+disassembler_constantpoolheader = Constant pool:
+disassembler_constantpool_class = constant #{0} class: #{1} {2}
+disassembler_constantpool_double = constant #{0} double: {1}
+disassembler_constantpool_float = constant #{0} float: {1}
+disassembler_constantpool_integer = constant #{0} integer: {1}
+disassembler_constantpool_long = constant #{0} long: {1}
+disassembler_constantpool_string = constant #{0} string: #{1} {2}
+disassembler_constantpool_fieldref = constant #{0} field_ref: #{1}.#{2} {3}.{4} {5}
+disassembler_constantpool_interfacemethodref = constant #{0} interface_method_ref: #{1}.#{2} {3}.{4} {5}
+disassembler_constantpool_methodref = constant #{0} method_ref: #{1}.#{2} {3}.{4} {5}
+disassembler_constantpool_name_and_type = constant #{0} name_and_type: #{1}.#{2} {3} {4}
+disassembler_constantpool_utf8 = constant #{0} utf8: {1}
+disassembler_annotationdefaultheader = Annotation Default:\ 
+disassembler_annotationdefaultvalue= {0} (constant type)
+disassembler_annotationenumvalue = {2}.{3}(enum type #{0}.#{1})
+disassembler_annotationclassvalue = {1} (#{0} class type)
+disassembler_annotationannotationvalue = annotation value =
+disassembler_annotationarrayvaluestart = [
+disassembler_annotationarrayvalueend = ]
+disassembler_annotationentrystart = #{0} @{1}(
+disassembler_annotationentryend = )
+disassembler_annotationcomponent = #{0} {1}=
+disassembler_runtimevisibleannotationsattributeheader= RuntimeVisibleAnnotations:\ 
+disassembler_runtimeinvisibleannotationsattributeheader= RuntimeInvisibleAnnotations:\ 
+disassembler_runtimevisibleparameterannotationsattributeheader= RuntimeVisibleParameterAnnotations:\ 
+disassembler_runtimeinvisibleparameterannotationsattributeheader= RuntimeInvisibleParameterAnnotations:\ 
+disassembler_parameterannotationentrystart=Number of annotations for parameter {0}: {1}
 
 ### classfileformat decoding
-classfileformat.versiondetails =\ (version {0} : {1}.{2}, {3})
-classfileformat.methoddescriptor =Method descriptor 
-classfileformat.fieldddescriptor =Field descriptor 
-classfileformat.maxStack = Stack: 
-classfileformat.maxLocals = Locals: 
-classfileformat.superflagisnotset = no super bit
-classfileformat.superflagisset = super bit
-classfileformat.clinitname = {}
+classfileformat_versiondetails =\ (version {0} : {1}.{2}, {3})
+classfileformat_methoddescriptor = // Method descriptor #{0} {1}
+classfileformat_fieldddescriptor = // Field descriptor #{0} {1}
+classfileformat_stacksAndLocals= // Stack: {0}, Locals: {1}
+classfileformat_superflagisnotset = no super bit
+classfileformat_superflagisset = super bit
+classfileformat_clinitname = '{'}
+classformat_classformatexception = Class Format Exception
 
 ### string displayed for each opcode
-classformat.invokeinterfacemethod =\ <Interface method 
-classformat.invokeinterfacemethodclose = >
-classformat.invokespecialconstructor =\ <Constructor 
-classformat.invokespecialconstructorclose = >
-classformat.invokespecialmethod =\ <Method 
-classformat.invokespecialmethodclose = >
-classformat.invokestaticmethod =\ <Method 
-classformat.invokestaticmethodclose = >
-classformat.invokevirtualmethod =\ <Method 
-classformat.invokevirtualmethodclose = >
-classformat.getfield = \ <Field 
-classformat.getfieldclose = >
-classformat.getstatic = \ <Field 
-classformat.getstaticclose = >
-classformat.putstatic =\ <Field 
-classformat.putstaticclose = >
-classformat.putfield =\ <Field 
-classformat.putfieldclose = >
-classformat.nargs =\ [nargs : 
-classformat.interfacemethodrefindex = ] #
-classfileformat.anyexceptionhandler=any
-classfileformat.fielddescriptorindex=#
-classfileformat.exceptiontablefrom=[pc: 
-classfileformat.exceptiontableto=, pc: 
-classfileformat.exceptiontablegoto=] -> 
-classfileformat.exceptiontablewhen =\ when : 
-classfileformat.linenumbertablefrom=[pc: 
-classfileformat.linenumbertableto=, line: 
-classfileformat.linenumbertableclose=]
-classfileformat.localvariabletablefrom=[pc: 
-classfileformat.localvariabletableto=, pc: 
-classfileformat.localvariabletablelocalname=] local: 
-classfileformat.localvariabletablelocalindex=\ index: 
-classfileformat.localvariabletablelocaltype=\ type: 
\ No newline at end of file
+classformat_anewarray = {0} {2} [{1}]
+classformat_checkcast = {0} {2} [{1}]
+classformat_instanceof = {0} {2} [{1}]
+classformat_ldc_w_class = {0} <Class {2}> [{1}]
+classformat_ldc_w_float = {0} <Float {2}> [{1}]
+classformat_ldc_w_integer = {0} <Integer {2}> [{1}]
+classformat_ldc_w_string = {0} <String "{2}"> [{1}]
+classformat_ldc2_w_long = {0} <Long {2}> [{1}]
+classformat_ldc2_w_double = {0} <Double {2}> [{1}]
+classformat_multianewarray = {0} {2}{3} [{1}]
+classformat_new = {0} {2} [{1}]
+classformat_iinc = {0} {1} {2} [{3}]
+classformat_invokespecial = {0} {2}.{3}{4} [{1}]
+classformat_invokespecial_compact ={0} {2} [{1}]
+classformat_invokeinterface ={0} {3}.{4}{5} [{1}] [nargs: {2}]
+classformat_invokeinterface_compact ={0} {3} [{1}] [nargs: {2}]
+classformat_invokestatic ={0} {2}.{3}{4} [{1}]
+classformat_invokestatic_compact ={0} {2} [{1}]
+classformat_invokevirtual ={0} {2}.{3}{4} [{1}]
+classformat_invokevirtual_compact ={0} {2} [{1}]
+classformat_getfield ={0} {2}.{3} {4} [{1}]
+classformat_getstatic ={0} {2}.{3} {4} [{1}]
+classformat_putstatic ={0} {2}.{3} {4} [{1}]
+classformat_putfield ={0} {2}.{3} {4} [{1}]
+classformat_newarray_boolean = {0} boolean [{1}]
+classformat_newarray_char = {0} char [{1}]
+classformat_newarray_float = {0} float [{1}]
+classformat_newarray_double = {0} double [{1}]
+classformat_newarray_byte = {0} byte [{1}]
+classformat_newarray_short = {0} short [{1}]
+classformat_newarray_int = {0} int [{1}]
+classformat_newarray_long = {0} long [{1}]
+classformat_store = {0} [{1}]
+classformat_load = {0} [{1}]
+classfileformat_anyexceptionhandler=any
+classfileformat_exceptiontableentry = [pc: {0}, pc: {1}] -> {2} when : {3}
+classfileformat_linenumbertableentry = [pc: {0}, line: {1}]
+classfileformat_localvariabletableentry = [pc: {0}, pc: {1}] local: {2} index: {3} type: {4}
diff --git a/org.eclipse.jdt.core/notes/API_changes.html b/org.eclipse.jdt.core/notes/API_changes.html
index 333a034..ca0299a 100644
--- a/org.eclipse.jdt.core/notes/API_changes.html
+++ b/org.eclipse.jdt.core/notes/API_changes.html
@@ -4,23 +4,26 @@
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="Author" content="IBM">
    <title>JDT/Core Breaking API changes</title>
-
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
-<body>
-
 <body text="#000000" bgcolor="#FFFFFF">
 &nbsp;
 
 <table border=0 cellspacing=5 cellpadding=2 width="100%" >
   <tr> 
-    <td align=left width="72%">
-      <font face="Verdana, Arial, Helvetica" size="+3"><b>jdt core - Breaking API changes from R2.1 to R3.0</b></font>
-      <br><font face="Arial, Helvetica, sans-serif" size="-2" color="#8080ff">java development tooling core</font></td>
+    <td align="left" width="72%" class="title1">
+      <font size="+3"><b>jdt core - Breaking API changes from R2.1 to R3.0</b></font>
+	</td>
+  </tr>
+  <tr>
+	<td align="left" width="72%" class="title2">
+	  <font size="-2" color="#8080ff">java development tooling core</font>
+	</td>
   </tr>
 	<tr><td>&nbsp;</td></tr>
   <tr>
-  	<td>
-	  <font face="Arial, Helvetica, sans-serif" size="-1">
+  	<td align="left" width="72%" class="title3">
+	  <font size="-1">
 	  This document lists all API changes (breaking or not) that occured between R2.1 and R3.0 and how to migrate from the R2.1 API to
 	  the R3.0 API.
 	  </font>
@@ -157,10 +160,10 @@
  * @param monitor a progress monitor for reporting operation progress
  * @exception JavaModelException if the classpath could not be updated. Reasons
  * include:
- *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  *  - Two or more entries specify source roots with the same or overlapping paths (NAME_COLLISION)
  *  - A entry of kind <code>CPE_PROJECT</code> refers to this project (INVALID_PATH)
- *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  *  - The output location path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
  *  - The output location path is not an absolute path (<code>RELATIVE_PATH</code>)
  *  - The output location path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
diff --git a/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html
index d7c6de2..e6fafcf 100644
--- a/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/notes/R20_buildnotes_jdt-core.html
@@ -5,23 +5,24 @@
    <meta name="Author" content="IBM">
    <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
    <title>JDT/Core Release Notes</title>
-
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
-<body>
 
 <body text="#000000" bgcolor="#FFFFFF">
-&nbsp;
-
 <table border=0 cellspacing=5 cellpadding=2 width="100%" >
   <tr> 
-    <td align=left width="72%">
-      <font face="Verdana, Arial, Helvetica" size="+3"><b>jdt core - build notes R2.0</b></font>
-      <br><font face="Arial, Helvetica, sans-serif" size="-2" color="#8080ff">java development tooling core</font></td>
+    <td align="left" width="72%" class="title1">
+      <font size="+3"><b>jdt core - build notes R2.0</b></font>
+	</td>
+  </tr>
+  <tr>
+  <td align="left" width="72%" class="title1">
+      <font size="-2" color="#8080ff">java development tooling core</font></td>
   </tr>
 	<tr><td>&nbsp;</td></tr>
   <tr>
-  	<td>
-	  <font face="Arial, Helvetica, sans-serif" size="-1">
+  	<td align="left" width="72%" class="title3">
+	  <font size="-1">
 	  Here are the build notes for the Eclipse JDT/Core plug-in project 
 	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
 	  describing bug resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
diff --git a/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html
index 88789a4..8c5b6d5 100644
--- a/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/notes/R21_buildnotes_jdt-core.html
@@ -5,23 +5,24 @@
    <meta name="Author" content="IBM">
    <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
    <title>JDT/Core Release Notes</title>
-
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
-<body>
-
 <body text="#000000" bgcolor="#FFFFFF">
-&nbsp;
-
 <table border=0 cellspacing=5 cellpadding=2 width="100%" >
   <tr> 
-    <td align=left width="72%">
-      <font face="Verdana, Arial, Helvetica" size="+3"><b>jdt core - build notes 2.1 stream</b></font>
-      <br><font face="Arial, Helvetica, sans-serif" size="-2" color="#8080ff">java development tooling core</font></td>
+    <td align="left" width="72%" class="title1">
+      <font size="+3"><b>jdt core - build notes 2.1 stream</b></font>
+	</td>
+  </tr>
+  <tr>
+	  <td align="left" width="72%" class="title2">
+	  	  <font size="-2" color="#8080ff">java development tooling core</font>
+	  </td>
   </tr>
 	<tr><td>&nbsp;</td></tr>
   <tr>
-  	<td>
-	  <font face="Arial, Helvetica, sans-serif" size="-1">
+  	<td class="title3">
+	  <font size="-1">
 	  Here are the build notes for the Eclipse JDT/Core plug-in project 
 	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
 	  describing <a href="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
diff --git a/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html b/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html
index b71803e..a07cf9c 100644
--- a/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/notes/R30_buildnotes_jdt-core.html
@@ -3,25 +3,26 @@
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="Author" content="IBM">
-   <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
    <title>JDT/Core Release Notes</title>
-
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
-<body>
 
 <body text="#000000" bgcolor="#FFFFFF">
-&nbsp;
-
 <table border=0 cellspacing=5 cellpadding=2 width="100%" >
   <tr> 
-    <td align=left width="72%">
-      <font face="Verdana, Arial, Helvetica" size="+3"><b>jdt core - build notes 3.0 stream</b></font>
-      <br><font face="Arial, Helvetica, sans-serif" size="-2" color="#8080ff">java development tooling core</font></td>
+    <td align="left" width="72%" class="title1">
+      <font size="+3"><b>jdt core - build notes 3.0 stream</b></font>
+    </td>
+  </tr>
+  <tr>
+    <td align="left" width="72%" class="title2">
+		<font size="-2" color="#8080ff">java development tooling core</font>
+	</td>
   </tr>
 	<tr><td>&nbsp;</td></tr>
   <tr>
-  	<td>
-	  <font face="Arial, Helvetica, sans-serif" size="-1">
+  	<td class="title3">
+	  <font size="-1">
 	  Here are the build notes for the Eclipse JDT/Core plug-in project 
 	  <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/main.html"><b>org.eclipse.jdt.core</b></a>, 
 	  describing <a href="http://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch. 
@@ -1293,7 +1294,6 @@
 <li><code>getCommentList()</code>: Returns a list of the comments encountered while parsing the compilation unit.</li>
 <li><code>getExtendedStartPosition(ASTNode)</code>: Returns the extended start position of the given node.</li>
 <li><code>getExtendedLength(ASTNode)</code>: Returns the extended source length of the given node.</li>
-</li>
 </ul>
 Unlike <code>ASTNode#getStartPosition()</code> and <code>ASTNode#getLength()</code>, the extended source range may include
 comments and whitespace immediately before or after the normal source range for the node.
@@ -3955,10 +3955,10 @@
  * @param monitor a progress monitor for reporting operation progress
  * @exception JavaModelException if the classpath could not be updated. Reasons
  * include:
- *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  *  - Two or more entries specify source roots with the same or overlapping paths (NAME_COLLISION)
  *  - A entry of kind <code>CPE_PROJECT</code> refers to this project (INVALID_PATH)
- *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
+ *  - This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
  *  - The output location path refers to a location not contained in this project (<code>PATH_OUTSIDE_PROJECT</code>)
  *  - The output location path is not an absolute path (<code>RELATIVE_PATH</code>)
  *  - The output location path is nested inside a package fragment root of this project (<code>INVALID_PATH</code>)
diff --git a/org.eclipse.jdt.core/notes/porting_guide.html b/org.eclipse.jdt.core/notes/porting_guide.html
index 4786a55..229a7c6 100644
--- a/org.eclipse.jdt.core/notes/porting_guide.html
+++ b/org.eclipse.jdt.core/notes/porting_guide.html
@@ -5,7 +5,8 @@
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 <title>JDT Core Porting Guide</title>
 <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
-<meta name="ProgId" content="FrontPage.Editor.Document">
+<meta name="ProgId" content="FrontPage.Editor.Document">	 
+   <link rel="stylesheet" href="../jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
 
 <body>
@@ -16,9 +17,9 @@
 <h2>Required changes for 3.0</h2>
 <p>None.</p>
 <h2>Recommended changes for 3.0</h2>
-<b><font face="Times New Roman">
+<b class="title1">
 <p>[JDT only] Improved support for working copies (package org.eclipse.jdt.core)</p>
-</font></b>
+</b>
 <p>The Java model working copy facility has been reworked in 3.0 to provide
 greatly increased functionality. Prior to 3.0, the Java model allowed creation
 of individual working copies of compilation units. Changes could be made to the
@@ -305,9 +306,9 @@
   </li>
 </ul>
 
-<b><font face="Times New Roman">
+<b class="title1">
 <p>[JDT only] Java search participants (package org.eclipse.jdt.core.search)</p>
-</font></b>
+</b>
 <p>Languages close to Java (such as JSP, SQLJ, JWS, etc.) should be able to participate in Java searching. 
 In particular implementors of such languages should be able to:
 <ul>
diff --git a/org.eclipse.jdt.core/plugin.properties b/org.eclipse.jdt.core/plugin.properties
index cee64cb..f1c9b2e 100644
--- a/org.eclipse.jdt.core/plugin.properties
+++ b/org.eclipse.jdt.core/plugin.properties
@@ -1,10 +1,10 @@
 ###############################################################################
 # Copyright (c) 2000, 2004 IBM Corporation and others.
-# All rights reserved. This program and the accompanying materials 
-# are made available under the terms of the Common Public License v1.0
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v10.html
-# 
+# http://www.eclipse.org/legal/epl-v10.html
+#
 # Contributors:
 #     IBM Corporation - initial API and implementation
 ###############################################################################
@@ -21,4 +21,5 @@
 javaTaskName=Java Task
 javaPropertiesName=Java Properties File
 javaSourceName=Java Source File
-jarManifestName=JAR Manifest File
\ No newline at end of file
+jarManifestName=JAR Manifest File
+extraJavaLikeFileExtensions=Extra Java-like File Extensions
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml
index 7337604..89024aa 100644
--- a/org.eclipse.jdt.core/plugin.xml
+++ b/org.eclipse.jdt.core/plugin.xml
@@ -21,16 +21,11 @@
     <import plugin="org.apache.ant" optional="true"/>
     <import plugin="org.eclipse.team.core" optional="true"/>
 </requires>
-	
+
 <!-- =================================================================================== -->
 <!-- Runtime Libraries                                                                   -->
 <!-- =================================================================================== -->
 
-<runtime>
-  <library name="jdtcore.jar">  
-     <export name="*"/>
-  </library> 
-</runtime>
 
 <!-- =================================================================================== -->
 <!-- Extension Point: Initializers of Classpath Variables                                -->
@@ -56,7 +51,6 @@
 	id="codeFormatter"
 	schema="schema/codeFormatter.exsd"/>
 
-
 <!-- =================================================================================== -->
 <!-- Extension: Java Nature                                                              -->
 <!-- =================================================================================== -->
diff --git a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
index f1e97e2..07085b2 100644
--- a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
+++ b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
@@ -112,9 +112,9 @@
       <documentation>

          Copyright (c) 2000, 2004 IBM Corporation and others.&lt;br&gt;

 All rights reserved. This program and the accompanying materials are made 

-available under the terms of the Common Public License v1.0 which accompanies 

-this distribution, and is available at &lt;a 

-href=&quot;http://www.eclipse.org/legal/cpl-v10.html&quot;&gt;http://www.eclipse.org/legal/cpl-v10.html&lt;/a&gt;

+available under the terms of the Eclipse Public License v1.0 which accompanies 

+this distribution, and is available at &lt;a

+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;

       </documentation>

    </annotation>

 

diff --git a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
index 6f8e08e..ca78aa8 100644
--- a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
+++ b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
@@ -112,9 +112,9 @@
       <documentation>

          Copyright (c) 2000, 2004 IBM Corporation and others.&lt;br&gt;

 All rights reserved. This program and the accompanying materials are made 

-available under the terms of the Common Public License v1.0 which accompanies 

-this distribution, and is available at &lt;a 

-href=&quot;http://www.eclipse.org/legal/cpl-v10.html&quot;&gt;http://www.eclipse.org/legal/cpl-v10.html&lt;/a&gt;

+available under the terms of the Eclipse Public License v1.0 which accompanies 

+this distribution, and is available at &lt;a

+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;

       </documentation>

    </annotation>

 

diff --git a/org.eclipse.jdt.core/schema/codeFormatter.exsd b/org.eclipse.jdt.core/schema/codeFormatter.exsd
index b5aa9e8..4fe77e6 100644
--- a/org.eclipse.jdt.core/schema/codeFormatter.exsd
+++ b/org.eclipse.jdt.core/schema/codeFormatter.exsd
@@ -101,11 +101,11 @@
       </appInfo>

       <documentation>

          Copyright (c) 2000, 2004 IBM Corporation and others.&lt;br&gt;
-All rights reserved. This program and the accompanying materials are made 
-available under the terms of the Common Public License v1.0 which accompanies 
-this distribution, and is available at &lt;a 
-href=&quot;http://www.eclipse.org/legal/cpl-v10.html&quot;&gt;http://www.eclipse.org/legal/cpl-v10.html&lt;/a&gt;

-      </documentation>

+All rights reserved. This program and the accompanying materials are made 

+available under the terms of the Eclipse Public License v1.0 which accompanies 

+this distribution, and is available at &lt;a

+href=&quot;http://www.eclipse.org/legal/epl-v10.html&quot;&gt;http://www.eclipse.org/legal/epl-v10.html&lt;/a&gt;

+     </documentation>

    </annotation>

 

 </schema>

diff --git a/org.eclipse.jdt.core/schema/compiler.dtd b/org.eclipse.jdt.core/schema/compiler.dtd
new file mode 100644
index 0000000..bdafe25
--- /dev/null
+++ b/org.eclipse.jdt.core/schema/compiler.dtd
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!ELEMENT compiler (error*,command_line,options,classpaths,error*,sources*,stats?,exception*)>
+<!ELEMENT command_line (argument*)>
+<!ELEMENT options (option*)>
+<!ELEMENT classpaths (classpath+)>
+<!ELEMENT error (#PCDATA)>
+<!ELEMENT sources (source+)>
+<!ELEMENT source (problems*,tasks*,(classfile | error)*)>
+<!ELEMENT problems (problem+)>
+<!ELEMENT problem (message,source_context,arguments)>
+<!ELEMENT arguments (argument+)>
+<!ELEMENT tasks (task+)>
+<!ELEMENT task (message, source_context)>
+<!ELEMENT stats (time?,number_of_lines?,problem_summary?,number_of_classfiles?)>
+<!ELEMENT argument (#PCDATA)>
+<!ELEMENT option (#PCDATA)>
+<!ELEMENT classpath (#PCDATA)>
+<!ELEMENT message (#PCDATA)>
+<!ELEMENT number_of_lines (#PCDATA)>
+<!ELEMENT time (#PCDATA)>
+<!ELEMENT number_of_classfiles (#PCDATA)>
+<!ELEMENT classfile (#PCDATA)>
+<!ELEMENT source_context (#PCDATA)>
+<!ELEMENT problem_summary (#PCDATA)>
+<!ELEMENT exception (#PCDATA)>
+<!ATTLIST argument value CDATA #REQUIRED>
+<!ATTLIST option key   CDATA #REQUIRED
+				 value CDATA #REQUIRED
+>
+<!ATTLIST classpath path CDATA #REQUIRED
+                    id   CDATA #REQUIRED
+>
+<!ATTLIST source path CDATA #REQUIRED>
+<!ATTLIST problems problems CDATA #REQUIRED
+				   errors   CDATA #REQUIRED
+				   warnings CDATA #REQUIRED
+>
+<!ATTLIST tasks tasks CDATA #REQUIRED>
+<!ATTLIST problem charEnd   CDATA #REQUIRED
+				  charStart CDATA #REQUIRED
+				  severity  CDATA #REQUIRED
+				  line      CDATA #REQUIRED
+				  id        CDATA #REQUIRED
+>
+<!ATTLIST message value CDATA #REQUIRED>
+<!ATTLIST source_context value       CDATA #REQUIRED
+                         sourceStart CDATA #REQUIRED
+                         sourceEnd   CDATA #REQUIRED
+>
+<!ATTLIST task charEnd   CDATA #REQUIRED
+			  charStart CDATA #REQUIRED
+			  line      CDATA #REQUIRED
+>
+<!ATTLIST classfile path CDATA #REQUIRED>
+<!ATTLIST error message CDATA #REQUIRED>
+<!ATTLIST problem_summary problems CDATA #REQUIRED
+                          errors   CDATA #REQUIRED
+                          warnings CDATA #REQUIRED
+                          tasks    CDATA #REQUIRED
+>
+<!ATTLIST number_of_classfiles value CDATA #REQUIRED>
+<!ATTLIST time value CDATA #REQUIRED>
+<!ATTLIST number_of_lines value CDATA #REQUIRED>
+<!ATTLIST compiler name      CDATA #REQUIRED
+                  copyright CDATA #REQUIRED
+                  version   CDATA #REQUIRED
+>
+<!ATTLIST exception class CDATA #REQUIRED
+			        message CDATA #REQUIRED
+>
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/scripts/GenerateBuildScript.java b/org.eclipse.jdt.core/scripts/GenerateBuildScript.java
index 187e56d..ea42020 100644
--- a/org.eclipse.jdt.core/scripts/GenerateBuildScript.java
+++ b/org.eclipse.jdt.core/scripts/GenerateBuildScript.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
diff --git a/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml b/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml
index 4435924..742ef03 100644
--- a/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml
+++ b/org.eclipse.jdt.core/scripts/export-batch-jdtcom.xml
@@ -16,10 +16,18 @@
 		<mkdir dir="${dest}" />
 
 		<echo message="UPDATE jdtcom.jar" />
-		<jar 
+		<zip zipfile="${dest}/jdtcom.jar">
+			<fileset dir=".">
+			  <include name="META-INF/**" />
+	        </fileset>
+	        <fileset dir="bin" includes="org/eclipse/jdt/internal/compiler/**,org/eclipse/jdt/core/compiler/**"/>
+		</zip>
+<!--		<jar 
 			jarfile="${dest}/jdtcom.jar"
 			basedir="bin"
-			includes="org/eclipse/jdt/internal/compiler/**,org/eclipse/jdt/core/compiler/**" />
+			includes="org/eclipse/jdt/internal/compiler/**,org/eclipse/jdt/core/compiler/**"
+			manifest="META-INF/MANIFEST.MF"
+			index="true"/> -->
 		
 		<echo message="UPDATE jdtcomsrc.zip" />
 		<zip zipfile="${dest}/jdtcomsrc.zip">
diff --git a/org.eclipse.jdt.core/scripts/export-ejavac.xml b/org.eclipse.jdt.core/scripts/export-ejavac.xml
index a04444f..594271c 100644
--- a/org.eclipse.jdt.core/scripts/export-ejavac.xml
+++ b/org.eclipse.jdt.core/scripts/export-ejavac.xml
@@ -2,11 +2,11 @@
 <project name="export-executable" default="build" basedir="..">
 
 	<property name="version" value="310" />
-	<property name="gcc-path" value="C:/java_tools/thisiscool-gcc/gcc-4.0" />
+	<property name="gcc-path" value="d:/gcj/thisiscool-gcc/gcc-4.0" />
 	<property name="binaryname" value="ejavac${version}" />
 	<property name="dest" value="../../bingcj/" />
 	<property name="work" value="${dest}tmp/" />
-	<property name="source" value="C:/eclipse/workspaces/head/org.eclipse.jdt.core" />
+	<property name="source" value="d:/eclipse/workspaces/dev3.1/plugins/org.eclipse.jdt.core" />
 	<property name="gcj_script_name" value="export-executable.xml"/>
 
     <target name="build">
diff --git a/org.eclipse.jdt.core/scripts/exportplugin.xml b/org.eclipse.jdt.core/scripts/exportplugin.xml
index 69af5f3..0433f0e 100644
--- a/org.eclipse.jdt.core/scripts/exportplugin.xml
+++ b/org.eclipse.jdt.core/scripts/exportplugin.xml
@@ -63,29 +63,28 @@
 	<delete dir="${plugin-dir}" />
 	<mkdir dir="${plugin-dir}" />
 
-	<echo message="UPDATE jdtcore.jar" />
-	<jar 
-		jarfile="${plugin-dir}/jdtcore.jar"
-		basedir="bin"/>
-		
 	<echo message="UPDATE jdtCompilerAdapter.jar" />
-	<jar 
+  	<jar 
 		jarfile="${plugin-dir}/jdtCompilerAdapter.jar"
 		basedir="antbin"/>
 
-	<echo message="UPDATE plugin.xml" />
-	<copy file="plugin.xml" todir="${plugin-dir}" />
-	<echo message="UPDATE plugin.properties" />
-	<copy file="plugin.properties" todir="${plugin-dir}" />
+	<echo message="UPDATE ${plugin}_${jdt_core_version}.jar" />
+	<zip zipfile="${plugin-dir}/${plugin}_${jdt_core_version}.jar">
+		<fileset dir=".">
+		  <include name="plugin.xml" />
+		  <include name="plugin.properties" />
+		  <include name="META-INF/**" />
+	      <include name=".options"/>
+          <include name="about.html"/>
+        </fileset>
+        <fileset dir="bin" />
+        <fileset file="${plugin-dir}/jdtCompilerAdapter.jar"/>
+	</zip>
 
-	<echo message="UPDATE .options" />
-	<copy file=".options" todir="${plugin-dir}" />
-
-	<echo message="UPDATE about.html" />
-	<copy file="about.html" todir="${plugin-dir}" />
-
+	<delete file="${plugin-dir}/jdtCompilerAdapter.jar"/>
 	<echo message="UPDATE jdtcoresrc.zip" />
 	<zip zipfile="${plugin-dir}/jdtcoresrc.zip">
+        <fileset file="component.xml"/>	
 	    <fileset dir="batch" />
 	    <fileset dir="codeassist" />
 	    <fileset dir="compiler" />
@@ -100,11 +99,13 @@
 	<zip zipfile="${plugin-dir}/jdtCompilerAdaptersrc.zip">
 		<fileset dir="antadapter" />
 	</zip>	    
-
 	<echo message="UPDATE ${export-dir}/../${plugin}_${jdt_core_version}.zip" />
 	<zip zipfile="${export-dir}/../${plugin}_${jdt_core_version}.zip"
 	    basedir="${export-dir}" 
 	    includes="${plugin}_${jdt_core_version}/**"	/>		
+	<!--
+		<delete dir="${plugin-dir}" />
+	-->
 </target>
 
 <target name="zz_internal_export_structure">
diff --git a/org.eclipse.jdt.core/scripts/oldexportplugin.xml b/org.eclipse.jdt.core/scripts/oldexportplugin.xml
new file mode 100644
index 0000000..16a1649
--- /dev/null
+++ b/org.eclipse.jdt.core/scripts/oldexportplugin.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- build script to create a plugin from ${plugin} -->
+<project name="${plugin}" default="export plug-in [_3.1.0]" basedir="..">
+
+<target name="export plug-in [_3.1.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="3.1.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_3.0.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="3.0.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.1.1]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.1.1"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.1.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.1.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.1.0] (directory structure)">
+	<antcall target="zz_internal_export_structure">
+		<param name="jdt_core_version" value="2.1.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.0.1]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.0.1"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_2.0.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="2.0.0"/>
+	</antcall>
+</target>
+
+<target name="export plug-in [_1.9.0]">
+	<antcall target="zz_internal_export">
+		<param name="jdt_core_version" value="1.9.0"/>
+	</antcall>
+</target>
+
+<target name="zz_internal_export">
+
+	<tstamp/>
+	<property name="export-dir" value="../../plugin-export" />
+	<property name="plugin" value="org.eclipse.jdt.core" />
+	<property name="plugin-dir" value="${export-dir}/${plugin}_${jdt_core_version}"/>
+
+	<echo message="TARGET: ${export-dir}" />
+	<mkdir dir="${export-dir}" />
+	<delete dir="${plugin-dir}" />
+	<mkdir dir="${plugin-dir}" />
+
+	<echo message="UPDATE jdtcore.jar" />
+	<jar 
+		jarfile="${plugin-dir}/jdtcore.jar"
+		basedir="bin"
+		manifest="META-INF/MANIFEST.MF"/>
+		
+	<echo message="UPDATE jdtCompilerAdapter.jar" />
+	<jar 
+		jarfile="${plugin-dir}/jdtCompilerAdapter.jar"
+		basedir="antbin"/>
+
+	<echo message="UPDATE plugin.xml" />
+	<copy file="plugin.xml" todir="${plugin-dir}" />
+	<echo message="UPDATE plugin.properties" />
+	<copy file="plugin.properties" todir="${plugin-dir}" />
+
+	<echo message="UPDATE .options" />
+	<copy file=".options" todir="${plugin-dir}" />
+
+	<echo message="UPDATE about.html" />
+	<copy file="about.html" todir="${plugin-dir}" />
+
+	<echo message="UPDATE jdtcoresrc.zip" />
+	<zip zipfile="${plugin-dir}/jdtcoresrc.zip">
+	    <fileset dir="batch" />
+	    <fileset dir="codeassist" />
+	    <fileset dir="compiler" />
+	    <fileset dir="dom" />
+	    <fileset dir="eval" />
+	    <fileset dir="formatter" />
+	    <fileset dir="model" />
+	    <fileset dir="search" />
+	</zip>		
+
+	<echo message="UPDATE jdtCompilerAdaptersrc.zip" />
+	<zip zipfile="${plugin-dir}/jdtCompilerAdaptersrc.zip">
+		<fileset dir="antadapter" />
+	</zip>	    
+
+	<echo message="UPDATE ${export-dir}/../${plugin}_${jdt_core_version}.zip" />
+	<zip zipfile="${export-dir}/../${plugin}_${jdt_core_version}.zip"
+	    basedir="${export-dir}" 
+	    includes="${plugin}_${jdt_core_version}/**"	/>		
+</target>
+
+<target name="zz_internal_export_structure">
+
+	<tstamp/>
+	<property name="export-dir" value="../../plugin-export" />
+	<property name="plugin" value="org.eclipse.jdt.core" />
+	<property name="bin_dest" value="${export-dir}/eclipse/plugins/${plugin}_${jdt_core_version}"/>
+	<property name="src_dest" value="${export-dir}/eclipse/plugins/org.eclipse.jdt.source_${jdt_core_version}/src/${plugin}_${jdt_core_version}"/>
+
+	<echo message="TARGET: ${export-dir}" />
+	<mkdir dir="${export-dir}" />
+	<delete dir="${bin_dest}" />
+	<delete dir="${src_dest}" />
+	<mkdir dir="${bin_dest}" />
+	<mkdir dir="${src_dest}" />
+
+	<echo message="UPDATE jdtcore.jar" />
+	<jar 
+		jarfile="${bin_dest}/jdtcore.jar"
+		basedir="bin" 
+		excludes="**/JDTCompilerAdapter.class,**/antadapter/*"/>
+		
+	<echo message="UPDATE jdtCompilerAdapter.jar" />
+	<jar 
+		jarfile="${bin_dest}/jdtCompilerAdapter.jar"
+		basedir="bin" 
+		includes="**/JDTCompilerAdapter.class,**/antadapter/*"/>
+
+	<echo message="UPDATE plugin.xml" />
+	<copy file="plugin.xml" todir="${bin_dest}" />
+	<echo message="UPDATE plugin.properties" />
+	<copy file="plugin.properties" todir="${bin_dest}" />
+
+	<echo message="UPDATE .options" />
+	<copy file=".options" todir="${bin_dest}" />
+
+	<echo message="UPDATE about.html" />
+	<copy file="about.html" todir="${bin_dest}" />
+
+	<echo message="UPDATE jdtcoresrc.zip" />
+	<zip zipfile="${src_dest}/jdtcoresrc.zip">
+	    <fileset dir="batch" />
+	    <fileset dir="codeassist" />
+	    <fileset dir="compiler" />
+	    <fileset dir="dom" />
+	    <fileset dir="eval" />
+	    <fileset dir="formatter" />
+	    <fileset dir="model" />
+	    <fileset dir="search" />
+	</zip>		
+</target>
+
+</project>
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java
index a44a317..53edb56 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldDeclarationMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java
index 9c28b74..9eea99b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/FieldReferenceMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java
index 4a45a72..a190524 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,7 +32,8 @@
 	/* Nature of searched element */
 	
 	/**
-	 * The searched element is a type.
+	 * The searched element is a type, which may include classes, interfaces,
+	 * enums, and annotation types.
 	 */
 	int TYPE= 0;
 
@@ -58,30 +59,46 @@
 
 	/**
 	 * The searched element is a class. 
-	 * More selective than using TYPE
+	 * More selective than using {@link #TYPE}.
 	 */
 	int CLASS= 5;
 
 	/**
 	 * The searched element is an interface.
-	 * More selective than using TYPE
+	 * More selective than using {@link #TYPE}.
 	 */
 	int INTERFACE= 6;
 
 	/**
 	 * The searched element is an enum.
-	 * More selective than using TYPE
+	 * More selective than using {@link #TYPE}.
+	 * @since 3.1
 	 */
 	int ENUM= 7;
 
 	/**
 	 * The searched element is an annotation type.
-	 * More selective than using TYPE
+	 * More selective than using {@link #TYPE}.
+	 * @since 3.1
 	 */
 	int ANNOTATION_TYPE= 8;
 
+	/**
+	 * The searched element is a class or enum type.
+	 * More selective than using {@link #TYPE}.
+	 * @since 3.1
+	 */
+	int CLASS_AND_ENUM= 9;
+
+	/**
+	 * The searched element is a class or interface type.
+	 * More selective than using {@link #TYPE}.
+	 * @since 3.1
+	 */
+	int CLASS_AND_INTERFACE= 10;
+
 	/* Nature of match */
-	
+
 	/**
 	 * The search result is a declaration.
 	 * Can be used in conjunction with any of the nature of searched elements
@@ -132,6 +149,25 @@
 	 * @since 2.0
 	 */
 	int WRITE_ACCESSES = 5;
+
+	/**
+	 * Ignore declaring type while searching result.
+	 * Can be used in conjunction with any of the nature of match.
+	 * @since 3.1
+	 */
+	int IGNORE_DECLARING_TYPE = 0x10;
+
+	/**
+	 * Ignore return type while searching result.
+	 * Can be used in conjunction with any of the nature of match.
+	 * Note that:
+	 * <ul>
+	 * 	<li>for fields search, pattern will ignore field type</li>
+	 * 	<li>this flag will have no effect for types search</li>
+	 *	</ul>
+	 * @since 3.1
+	 */
+	int IGNORE_RETURN_TYPE = 0x20;
 	
 	/* Syntactic match modes */
 	
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java
index 8035883..eecbd66 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchResultCollector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java
index 5aa54a7..dc4fe60 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/IJavaSearchScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java
index a893aa6..f4ba6ce 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ISearchPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java
index 218f797..dc17e1b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/ITypeNameRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,6 +18,7 @@
  * <p>
  * This interface may be implemented by clients.
  * </p>
+ * @deprecated Use abstract class {@link TypeNameRequestor} instead.
  */
 public interface ITypeNameRequestor {
 /**
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java
index ea42f42..fdcde13 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableDeclarationMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java
index f42bcdb..6236185 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/LocalVariableReferenceMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java
index 2bb5438..0019985 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodDeclarationMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java
index f6a9b2a..082e27e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/MethodReferenceMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java
index d94cfca..2f13304 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageDeclarationMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java
index 802ece0..24afd4d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/PackageReferenceMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java
index 7f06e61..1f6b9d9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchDocument.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
index 2ca000d..2d8e8a5 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchEngine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,6 +14,7 @@
 import org.eclipse.core.runtime.*;
 
 import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
 import org.eclipse.jdt.internal.core.search.*;
 import org.eclipse.jdt.internal.core.search.matching.*;
 
@@ -44,6 +45,7 @@
 			this.pattern = pattern;
 		}
 	}
+
 	/**
 	 * Internal adapter class.
 	 * @deprecated marking deprecated as it uses deprecated IJavaSearchResultCollector
@@ -78,15 +80,33 @@
 			this.resultCollector.done();
 		}
 	}
+
+	/**
+	 * Internal adapter class.
+	 * @deprecated marking deprecated as it uses deprecated ITypeNameRequestor
+	 */
+	class TypeNameRequestorAdapter implements IRestrictedAccessTypeRequestor {
+		ITypeNameRequestor nameRequestor;
+		TypeNameRequestorAdapter(ITypeNameRequestor requestor) {
+			this.nameRequestor = requestor;
+		}
+		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+			if (Flags.isInterface(modifiers)) {
+				nameRequestor.acceptInterface(packageName, simpleTypeName, enclosingTypeNames, path);
+			} else {
+				nameRequestor.acceptClass(packageName, simpleTypeName, enclosingTypeNames, path);
+			}
+		}
+	}
 		
 	// Search engine now uses basic engine functionalities
-	private SearchBasicEngine basicEngine;
-	
+	private BasicSearchEngine basicEngine;
+
 	/**
 	 * Creates a new search engine.
 	 */
 	public SearchEngine() {
-		this.basicEngine = new SearchBasicEngine();
+		this.basicEngine = new BasicSearchEngine();
 	}
 	
 	/**
@@ -102,7 +122,7 @@
 	 * @since 3.0
 	 */
 	public SearchEngine(ICompilationUnit[] workingCopies) {
-		this.basicEngine = new SearchBasicEngine(workingCopies);
+		this.basicEngine = new BasicSearchEngine(workingCopies);
 	}
 	/**
 	 * Creates a new search engine with a list of working copies that will take precedence over 
@@ -121,7 +141,7 @@
 		int length = workingCopies.length;
 		ICompilationUnit[] units = new ICompilationUnit[length];
 		System.arraycopy(workingCopies, 0, units, 0, length);
-		this.basicEngine = new SearchBasicEngine(units);
+		this.basicEngine = new BasicSearchEngine(units);
 	}
 	
 	/**
@@ -133,7 +153,7 @@
 	 * @since 3.0
 	 */
 	public SearchEngine(WorkingCopyOwner workingCopyOwner) {
-		this.basicEngine = new SearchBasicEngine(workingCopyOwner);
+		this.basicEngine = new BasicSearchEngine(workingCopyOwner);
 	}
 
 	/**
@@ -146,7 +166,7 @@
 	 * @exception JavaModelException if the hierarchy could not be computed on the given type
 	 */
 	public static IJavaSearchScope createHierarchyScope(IType type) throws JavaModelException {
-		return SearchBasicEngine.createHierarchyScope(type);
+		return BasicSearchEngine.createHierarchyScope(type);
 	}
 	
 	/**
@@ -163,7 +183,7 @@
 	 * @since 3.0
 	 */
 	public static IJavaSearchScope createHierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException {
-		return SearchBasicEngine.createHierarchyScope(type, owner);
+		return BasicSearchEngine.createHierarchyScope(type, owner);
 	}
 
 	/**
@@ -209,7 +229,7 @@
 	 * @since 2.0
 	 */
 	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements) {
-		return SearchBasicEngine.createJavaSearchScope(elements);
+		return BasicSearchEngine.createJavaSearchScope(elements);
 	}
 
 	/**
@@ -233,7 +253,7 @@
 	 * @since 2.0
 	 */
 	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, boolean includeReferencedProjects) {
-		return SearchBasicEngine.createJavaSearchScope(elements, includeReferencedProjects);
+		return BasicSearchEngine.createJavaSearchScope(elements, includeReferencedProjects);
 	}
 
 	/**
@@ -268,7 +288,7 @@
 	 * @since 3.0
 	 */
 	public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, int includeMask) {
-		return SearchBasicEngine.createJavaSearchScope(elements, includeMask);
+		return BasicSearchEngine.createJavaSearchScope(elements, includeMask);
 	}
 	
 	/**
@@ -369,7 +389,7 @@
 	 * @return a new workspace scope
 	 */
 	public static IJavaSearchScope createWorkspaceScope() {
-		return SearchBasicEngine.createWorkspaceScope();
+		return BasicSearchEngine.createWorkspaceScope();
 	}
 	/**
 	 * Returns a new default Java search participant.
@@ -378,7 +398,7 @@
 	 * @since 3.0
 	 */
 	public static SearchParticipant getDefaultSearchParticipant() {
-		return SearchBasicEngine.getDefaultSearchParticipant();
+		return BasicSearchEngine.getDefaultSearchParticipant();
 	}
 
 	/**
@@ -563,7 +583,7 @@
 		final int matchRule, 
 		int searchFor, 
 		IJavaSearchScope scope, 
-		final ITypeNameRequestor nameRequestor,
+		final TypeNameRequestor nameRequestor,
 		int waitingPolicy,
 		IProgressMonitor progressMonitor)  throws JavaModelException {
 		
@@ -572,6 +592,109 @@
 	}
 
 	/**
+	 * Searches for all top-level types and member types in the given scope matching any of the given qualifications
+	 * and type names in a case sensitive way.
+	 * 
+	 * @param qualifications the qualified name of the package/enclosing type of the searched types
+	 * @param typeNames the simple names of the searched types
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
+	 *		<li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.1
+	 */
+	public void searchAllTypeNames(
+		final char[][] qualifications, 
+		final char[][] typeNames,
+		IJavaSearchScope scope, 
+		final TypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		TypeNameRequestorWrapper requestorWrapper = new TypeNameRequestorWrapper(nameRequestor);
+		this.basicEngine.searchAllTypeNames(
+			qualifications,
+			typeNames,
+			SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
+			IJavaSearchConstants.TYPE,
+			scope,
+			requestorWrapper,
+			waitingPolicy,
+			progressMonitor);
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope.
+	 * The search can be selecting specific types (given a package or a type name
+	 * prefix and match modes). 
+	 * 
+	 * @param packageName the full name of the package of the searched types, or a prefix for this
+	 *						package, or a wild-carded string for this package.
+	 * @param typeName the dot-separated qualified name of the searched type (the qualification include
+	 *					the enclosing types if the searched type is a member type), or a prefix
+	 *					for this type, or a wild-carded string for this type.
+	 * @param matchRule one of
+	 * <ul>
+	 *		<li><code>SearchPattern.R_EXACT_MATCH</code> if the package name and type name are the full names
+	 *			of the searched types.</li>
+	 *		<li><code>SearchPattern.R_PREFIX_MATCH</code> if the package name and type name are prefixes of the names
+	 *			of the searched types.</li>
+	 *		<li><code>SearchPattern.R_PATTERN_MATCH</code> if the package name and type name contain wild-cards.</li>
+	 * </ul>
+	 * combined with <code>SearchPattern.R_CASE_SENSITIVE</code>,
+	 *   e.g. <code>R_EXACT_MATCH | R_CASE_SENSITIVE</code> if an exact and case sensitive match is requested, 
+	 *   or <code>R_PREFIX_MATCH</code> if a prefix non case sensitive match is requested.
+	 * @param searchFor one of
+	 * <ul>
+	 * 		<li><code>IJavaSearchConstants.CLASS</code> if searching for classes only</li>
+	 * 		<li><code>IJavaSearchConstants.INTERFACE</code> if searching for interfaces only</li>
+	 * 		<li><code>IJavaSearchConstants.TYPE</code> if searching for both classes and interfaces</li>
+	 * </ul>
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
+	 *		<li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.0
+	 *@deprecated Use {@link #searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor)} instead
+	 */
+	public void searchAllTypeNames(
+		final char[] packageName, 
+		final char[] typeName,
+		final int matchRule, 
+		int searchFor, 
+		IJavaSearchScope scope, 
+		final ITypeNameRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+		
+		this.basicEngine.searchAllTypeNames(packageName, typeName, matchRule, searchFor, scope, new TypeNameRequestorAdapter(nameRequestor), waitingPolicy, progressMonitor);
+	}
+
+	/**
 	 * Searches for all top-level types and member types in the given scope.
 	 * The search can be selecting specific types (given a package or a type name
 	 * prefix and match modes). 
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
index 40e93ae..c4129c9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -45,7 +45,7 @@
 	 * @see #getAccuracy()
 	 */
 	public static final int A_INACCURATE = 1;
-	
+
 	private Object element;
 	private int length;
 	private int offset;
@@ -57,7 +57,12 @@
 	private boolean insideDocComment = false;
 	
 	// store the rule used while reporting the match
-	private int matchRule = SearchPattern.R_EXACT_MATCH;
+	private int rule = SearchPattern.R_FULL_MATCH |
+								SearchPattern.R_EQUIVALENT_MATCH |
+								SearchPattern.R_ERASURE_MATCH;
+	
+	// store other necessary information
+	private boolean raw = false;
 
 	/**
 	 * Creates a new search match.
@@ -83,7 +88,10 @@
 		this.element = element;
 		this.offset = offset;
 		this.length = length;
-		this.accuracy = accuracy;
+		this.accuracy = accuracy & A_INACCURATE;
+		if (accuracy > A_INACCURATE) {
+			this.rule = accuracy & ~A_INACCURATE; // accuracy may have also some rule information
+		}
 		this.participant = participant;
 		this.resource = resource;
 	}
@@ -147,16 +155,60 @@
 	/**
 	 * Returns the rule used while creating the match.
 	 * 
-	 * @return the rule of the match. Legal values are combination of following
-	 * {@link SearchPattern} constants:
-	 * <ul>
-	 * 	<li>{@link SearchPattern#R_ERASURE_MATCH}</li>
-	 * 	<li>{@link SearchPattern#R_EQUIVALENT_MATCH}</li>
-	 * </ul>
+	 * @return one of {@link SearchPattern#R_FULL_MATCH}, {@link SearchPattern#R_EQUIVALENT_MATCH}
+	 * 	or {@link SearchPattern#R_ERASURE_MATCH}
 	 * @since 3.1
 	 */
-	public final int getMatchRule() {
-		return this.matchRule;
+	public final int getRule() {
+		return this.rule;
+	}
+
+	/**
+	 * Returns whether match element is compatible with searched pattern or not.
+	 * Note that equivalent matches are also erasure ones.
+	 * 
+	 * @return <code>true</code> if match element is compatible 
+	 * 				<code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isEquivalent() {
+		return isErasure() && (this.rule & SearchPattern.R_EQUIVALENT_MATCH) != 0;
+	}
+
+	/**
+	 * Returns whether match element only has same erasure than searched pattern or not.
+	 * Note that this is always true for both generic and non-generic element as soon
+	 * as the accuracy is accurate.
+	 * 
+	 * @return <code>true</code> if match element has same erasure
+	 * 				<code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isErasure() {
+		return (this.rule & SearchPattern.R_ERASURE_MATCH) != 0;
+	}
+
+	/**
+	 * Returns whether element matches exactly searched pattern or not.
+	 * Note that exact matches are also erasure and equivalent ones.
+	 * 
+	 * @return <code>true</code> if match is exact
+	 * 				<code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isExact() {
+		return isEquivalent() && (this.rule & SearchPattern.R_FULL_MATCH) != 0;
+	}
+
+	/**
+	 * Returns whether the associated element is a raw type/method or not.
+	 * 
+	 * @return <code>true</code> if this match is associated to a raw
+	 * type or method and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final boolean isRaw() {
+		return this.raw;
 	}
 
 	/**
@@ -240,16 +292,23 @@
 	/**
 	 * Returns the rule used while creating the match.
 	 * 
-	 * @param rule the rule to set. Legal values are combination of following
-	 * {@link SearchPattern} constants:
-	 * <ul>
-	 * 	<li>{@link SearchPattern#R_ERASURE_MATCH}</li>
-	 * 	<li>{@link SearchPattern#R_EQUIVALENT_MATCH}</li>
-	 * </ul>
+	 * @param rule one of {@link SearchPattern#R_FULL_MATCH}, {@link SearchPattern#R_EQUIVALENT_MATCH}
+	 * 	or {@link SearchPattern#R_ERASURE_MATCH}
 	 * @since 3.1
 	 */
-	public final void setMatchRule(int rule) {
-		this.matchRule = rule;
+	public final void setRule(int rule) {
+		this.rule = rule;
+	}
+
+	/**
+	 * Returns whether the associated element is a raw type/method or not.
+	 * 
+	 * @param raw <code>true</code> if this search match is associated to a raw
+	 * type or method and <code>false</code> otherwise
+	 * @since 3.1
+	 */
+	public final void setRaw(boolean raw) {
+		this.raw = raw;
 	}
 
 	/* (non-javadoc)
@@ -261,15 +320,15 @@
 		buffer.append("\n  accuracy="); //$NON-NLS-1$
 		buffer.append(this.accuracy == A_ACCURATE ? "ACCURATE" : "INACCURATE"); //$NON-NLS-1$ //$NON-NLS-2$
 		buffer.append("\n  rule="); //$NON-NLS-1$
-		if ((this.matchRule & SearchPattern.R_EQUIVALENT_MATCH) != 0) {
-			buffer.append("EQUIVALENT"); //$NON-NLS-1$
-			if ((this.matchRule & SearchPattern.R_ERASURE_MATCH) != 0)
-				buffer.append("+ERASURE"); //$NON-NLS-1$
-		} else if ((this.matchRule & SearchPattern.R_ERASURE_MATCH) != 0) {
-			buffer.append("ERASURE"); //$NON-NLS-1$
-		} else {
+		if ((this.rule & SearchPattern.R_FULL_MATCH) != 0) {
 			buffer.append("EXACT"); //$NON-NLS-1$
+		} else if ((this.rule & SearchPattern.R_EQUIVALENT_MATCH) != 0) {
+			buffer.append("EQUIVALENT"); //$NON-NLS-1$
+		} else if ((this.rule & SearchPattern.R_ERASURE_MATCH) != 0) {
+			buffer.append("ERASURE"); //$NON-NLS-1$
 		}
+		buffer.append("\n  raw="); //$NON-NLS-1$
+		buffer.append(this.raw);
 		buffer.append("\n  offset="); //$NON-NLS-1$
 		buffer.append(this.offset);
 		buffer.append("\n  length="); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
index 015958b..ee39ea4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchParticipant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
index 37a1bd9..84f57f6 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,10 +16,10 @@
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
 import org.eclipse.jdt.internal.core.LocalVariable;
-import org.eclipse.jdt.internal.core.ParameterizedSourceType;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
 import org.eclipse.jdt.internal.core.search.matching.*;
 
+
 /**
  * A search pattern defines how search results are found. Use <code>SearchPattern.createPattern</code>
  * to create a search pattern.
@@ -50,34 +50,38 @@
 	 * that is, the source of the search result equals the search pattern.
 	 */
 	public static final int R_EXACT_MATCH = 0;
+
 	/**
 	 * Match rule: The search pattern is a prefix of the search result.
 	 */
 	public static final int R_PREFIX_MATCH = 1;
+
 	/**
 	 * Match rule: The search pattern contains one or more wild cards ('*') where a 
 	 * wild-card can replace 0 or more characters in the search result.
 	 */
 	public static final int R_PATTERN_MATCH = 2;
+
 	/**
 	 * Match rule: The search pattern contains a regular expression.
 	 */
 	public static final int R_REGEXP_MATCH = 4;
+
 	/**
 	 * Match rule: The search pattern matches the search result only if cases are the same.
-	 * Can be combined to previous rules, e.g. R_EXACT_MATCH | R_CASE_SENSITIVE
+	 * Can be combined to previous rules, e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE}
 	 */
 	public static final int R_CASE_SENSITIVE = 8;
+
 	/**
 	 * Match rule: The search pattern matches search results as raw/parameterized types/methods with same erasure.
-	 * This mode has no effect on other java elements search.
+	 * This mode has no effect on other java elements search.<br>
 	 * Type search example:
 	 * 	<ul>
 	 * 	<li>pattern: <code>List&lt;Exception&gt;</code></li>
 	 * 	<li>match: <code>List&lt;Object&gt;</code></li>
 	 * 	</ul>
 	 * Method search example:
-	 * 	TODO (frederic) This mode is not implemented yet. It will be completed in next milestone.
 	 * 	<ul>
 	 * 	<li>declaration: <code>&lt;T&gt;foo(T t)</code></li>
 	 * 	<li>pattern: <code>&lt;Exception&gt;foo(new Exception())</code></li>
@@ -90,9 +94,10 @@
 	 * @since 3.1
 	 */
 	public static final int R_ERASURE_MATCH = 16;
+
 	/**
 	 * Match rule: The search pattern matches search results as raw/parameterized types/methods with equivalent type parameters.
-	 * This mode has no effect on other java elements search.
+	 * This mode has no effect on other java elements search.<br>
 	 * Type search example:
 	 * <ul>
 	 * 	<li>pattern: <code>List&lt;Exception&gt;</code></li>
@@ -105,7 +110,6 @@
 	 * 	</li>
 	 * 	</ul>
 	 * Method search example:
-	 * 	TODO (frederic) This mode is not implemented yet. It will be completed in next milestone.
 	 * 	<ul>
 	 * 	<li>declaration: <code>&lt;T&gt;foo(T t)</code></li>
 	 * 	<li>pattern: <code>&lt;Exception&gt;foo(new Exception())</code></li>
@@ -126,6 +130,13 @@
 	 */
 	public static final int R_EQUIVALENT_MATCH = 32;
 
+	/**
+	 * Match rule: The search pattern matches exactly the search result,
+	 * that is, the source of the search result equals the search pattern.
+	 * @since 3.1
+	 */
+	public static final int R_FULL_MATCH = 64;
+
 	private int matchRule;
 
 	/**
@@ -133,14 +144,22 @@
 	 * It can be exact match, prefix match, pattern match or regexp match.
 	 * Rule can also be combined with a case sensitivity flag.
 	 * 
-	 * @param matchRule one of R_EXACT_MATCH, R_PREFIX_MATCH, R_PATTERN_MATCH, R_REGEXP_MATCH combined with R_CASE_SENSITIVE,
-	 *   e.g. R_EXACT_MATCH | R_CASE_SENSITIVE if an exact and case sensitive match is requested, 
-	 *   or R_PREFIX_MATCH if a prefix non case sensitive match is requested.
-	 * [TODO (frederic) Expand spec for matchRule to allow R_ERASURE_MATCH ?
-     * If yes, we have a problem because getMatchRule() locks in set of existing values.]
+	 * @param matchRule one of {@link #R_EXACT_MATCH}, {@link #R_PREFIX_MATCH}, {@link #R_PATTERN_MATCH},
+	 * 	{@link #R_REGEXP_MATCH} combined with one of follwing values: {@link #R_CASE_SENSITIVE}, {@link #R_ERASURE_MATCH}
+	 * 	or {@link #R_EQUIVALENT_MATCH}.
+	 *		e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE} if an exact and case sensitive match is requested, 
+	 *		{@link #R_PREFIX_MATCH} if a prefix non case sensitive match is requested or {@link #R_EXACT_MATCH} | {@link #R_ERASURE_MATCH}
+	 *		if a non case sensitive and erasure match is requested.<br>
+	 * 	Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} have no effect
+	 * 	on non-generic types/methods search.<br>
+	 * 	Note also that default behavior for generic types/methods search is to find exact matches.
 	 */
 	public SearchPattern(int matchRule) {
 		this.matchRule = matchRule;
+		// Set full match implicit mode
+		if ((matchRule & (R_EQUIVALENT_MATCH | R_ERASURE_MATCH )) == 0) {
+			this.matchRule |= R_FULL_MATCH;
+		}
 	}
 
 	/**
@@ -155,162 +174,7 @@
 	public static SearchPattern createAndPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
 		return MatchLocator.createAndPattern(leftPattern, rightPattern);
 	}
-	
-	/**
-	 * Constructor pattern are formed by [declaringQualification.]type[(parameterTypes)]
-	 * e.g. java.lang.Object()
-	 *		Main(*)
-	 */
-	private static SearchPattern createConstructorPattern(String patternString, int limitTo, int matchRule) {
-	
-		Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/);
-		scanner.setSource(patternString.toCharArray());
-		final int InsideName = 1;
-		final int InsideParameter = 2;
-		
-		String declaringQualification = null, typeName = null, parameterType = null;
-		String[] parameterTypes = null;
-		int parameterCount = -1;
-		boolean foundClosingParenthesis = false;
-		int mode = InsideName;
-		int token;
-		try {
-			token = scanner.getNextToken();
-		} catch (InvalidInputException e) {
-			return null;
-		}
-		while (token != TerminalTokens.TokenNameEOF) {
-			switch(mode) {
-				// read declaring type and selector
-				case InsideName :
-					switch (token) {
-						case TerminalTokens.TokenNameDOT:
-							if (declaringQualification == null) {
-								if (typeName == null) return null;
-								declaringQualification = typeName;
-							} else {
-								String tokenSource = new String(scanner.getCurrentTokenSource());
-								declaringQualification += tokenSource + typeName;
-							}
-							typeName = null;
-							break;
-						case TerminalTokens.TokenNameLPAREN:
-							parameterTypes = new String[5];
-							parameterCount = 0;
-							mode = InsideParameter;
-							break;
-						case TerminalTokens.TokenNameWHITESPACE:
-							break;
-						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
-							if (typeName == null)
-								typeName = new String(scanner.getCurrentTokenSource());
-							else
-								typeName += new String(scanner.getCurrentTokenSource());
-					}
-					break;
-				// read parameter types
-				case InsideParameter :
-					switch (token) {
-						case TerminalTokens.TokenNameWHITESPACE:
-							break;
-						case TerminalTokens.TokenNameCOMMA:
-							if (parameterType == null) return null;
-							if (parameterTypes.length == parameterCount)
-								System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
-							parameterTypes[parameterCount++] = parameterType;
-							parameterType = null;
-							break;
-						case TerminalTokens.TokenNameRPAREN:
-							foundClosingParenthesis = true;
-							if (parameterType != null) {
-								if (parameterTypes.length == parameterCount)
-									System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
-								parameterTypes[parameterCount++] = parameterType;
-							}
-							break;
-						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
-							if (parameterType == null)
-								parameterType = new String(scanner.getCurrentTokenSource());
-							else
-								parameterType += new String(scanner.getCurrentTokenSource());
-					}
-					break;
-			}
-			try {
-				token = scanner.getNextToken();
-			} catch (InvalidInputException e) {
-				return null;
-			}
-		}
-		// parenthesis mismatch
-		if (parameterCount>0 && !foundClosingParenthesis) return null;
-		if (typeName == null) return null;
-	
-		char[] typeNameChars = typeName.toCharArray();
-		if (typeNameChars.length == 1 && typeNameChars[0] == '*') typeNameChars = null;
-			
-		char[] declaringQualificationChars = null;
-		if (declaringQualification != null) declaringQualificationChars = declaringQualification.toCharArray();
-		char[][] parameterTypeQualifications = null, parameterTypeSimpleNames = null;
-	
-		// extract parameter types infos
-		if (parameterCount >= 0) {
-			parameterTypeQualifications = new char[parameterCount][];
-			parameterTypeSimpleNames = new char[parameterCount][];
-			for (int i = 0; i < parameterCount; i++) {
-				char[] parameterTypePart = parameterTypes[i].toCharArray();
-				int lastDotPosition = CharOperation.lastIndexOf('.', parameterTypePart);
-				if (lastDotPosition >= 0) {
-					parameterTypeQualifications[i] = CharOperation.subarray(parameterTypePart, 0, lastDotPosition);
-					if (parameterTypeQualifications[i].length == 1 && parameterTypeQualifications[i][0] == '*') {
-						parameterTypeQualifications[i] = null;
-					} else {
-						// prefix with a '*' as the full qualification could be bigger (because of an import)
-						parameterTypeQualifications[i] = CharOperation.concat(IIndexConstants.ONE_STAR, parameterTypeQualifications[i]);
-					}
-					parameterTypeSimpleNames[i] = CharOperation.subarray(parameterTypePart, lastDotPosition+1, parameterTypePart.length);
-				} else {
-					parameterTypeQualifications[i] = null;
-					parameterTypeSimpleNames[i] = parameterTypePart;
-				}
-				if (parameterTypeSimpleNames[i].length == 1 && parameterTypeSimpleNames[i][0] == '*')
-					parameterTypeSimpleNames[i] = null;
-			}
-		}	
-		switch (limitTo) {
-			case IJavaSearchConstants.DECLARATIONS :
-				return new ConstructorPattern(
-					true,
-					false,
-					typeNameChars, 
-					declaringQualificationChars, 
-					parameterTypeQualifications, 
-					parameterTypeSimpleNames,
-					false,
-					matchRule);
-			case IJavaSearchConstants.REFERENCES :
-				return new ConstructorPattern(
-					false,
-					true,
-					typeNameChars, 
-					declaringQualificationChars, 
-					parameterTypeQualifications, 
-					parameterTypeSimpleNames,
-					false,
-					matchRule);
-			case IJavaSearchConstants.ALL_OCCURRENCES :
-				return new ConstructorPattern(
-					true,
-					true,
-					typeNameChars, 
-					declaringQualificationChars, 
-					parameterTypeQualifications, 
-					parameterTypeSimpleNames,
-					false,
-					matchRule);
-		}
-		return null;
-	}
+
 	/**
 	 * Field pattern are formed by [declaringType.]name[ type]
 	 * e.g. java.lang.String.serialVersionUID long
@@ -343,7 +207,7 @@
 								if (fieldName == null) return null;
 								declaringType = fieldName;
 							} else {
-								String tokenSource = new String(scanner.getCurrentTokenSource());
+								String tokenSource = scanner.getCurrentTokenString();
 								declaringType += tokenSource + fieldName;
 							}
 							fieldName = null;
@@ -354,9 +218,9 @@
 							break;
 						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
 							if (fieldName == null)
-								fieldName = new String(scanner.getCurrentTokenSource());
+								fieldName = scanner.getCurrentTokenString();
 							else
-								fieldName += new String(scanner.getCurrentTokenSource());
+								fieldName += scanner.getCurrentTokenString();
 					}
 					break;
 				// read type 
@@ -366,9 +230,9 @@
 							break;
 						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
 							if (type == null)
-								type = new String(scanner.getCurrentTokenSource());
+								type = scanner.getCurrentTokenString();
 							else
-								type += new String(scanner.getCurrentTokenSource());
+								type += scanner.getCurrentTokenString();
 					}
 					break;
 			}
@@ -423,86 +287,79 @@
 			if (typeSimpleName.length == 1 && typeSimpleName[0] == '*')
 				typeSimpleName = null;
 		}
+		// Create field pattern
+		boolean findDeclarations = false;
+		boolean readAccess = false;
+		boolean writeAccess = false;
 		switch (limitTo) {
 			case IJavaSearchConstants.DECLARATIONS :
-				return new FieldPattern(
-					true,
-					false,
-					false,
-					fieldNameChars,
-					declaringTypeQualification,
-					declaringTypeSimpleName,
-					typeQualification,
-					typeSimpleName,
-					matchRule);
+				findDeclarations = true;
+				break;
 			case IJavaSearchConstants.REFERENCES :
-				return new FieldPattern(
-					false,
-					true, // read access
-					true, // write access
-					fieldNameChars, 
-					declaringTypeQualification, 
-					declaringTypeSimpleName, 
-					typeQualification, 
-					typeSimpleName,
-					matchRule);
+				readAccess = true;
+				writeAccess = true;
+				break;
 			case IJavaSearchConstants.READ_ACCESSES :
-				return new FieldPattern(
-					false,
-					true, // read access only
-					false,
-					fieldNameChars, 
-					declaringTypeQualification, 
-					declaringTypeSimpleName, 
-					typeQualification, 
-					typeSimpleName,
-					matchRule);
+				readAccess = true;
+				break;
 			case IJavaSearchConstants.WRITE_ACCESSES :
-				return new FieldPattern(
-					false,
-					false,
-					true, // write access only
-					fieldNameChars, 
-					declaringTypeQualification, 
-					declaringTypeSimpleName, 
-					typeQualification, 
-					typeSimpleName,
-					matchRule);
+				writeAccess = true;
+				break;
 			case IJavaSearchConstants.ALL_OCCURRENCES :
-				return new FieldPattern(
-					true,
-					true, // read access
-					true, // write access
-					fieldNameChars, 
-					declaringTypeQualification, 
-					declaringTypeSimpleName, 
-					typeQualification, 
-					typeSimpleName,
-					matchRule);
+				findDeclarations = true;
+				readAccess = true;
+				writeAccess = true;
+				break;
 		}
-		return null;
+		return new FieldPattern(
+				findDeclarations,
+				readAccess,
+				writeAccess,
+				fieldNameChars,
+				declaringTypeQualification,
+				declaringTypeSimpleName,
+				typeQualification,
+				typeSimpleName,
+				matchRule);
 	}
+
 	/**
-	 * Method pattern are formed by [declaringType.]selector[(parameterTypes)][ returnType]
-	 * e.g. java.lang.Runnable.run() void
-	 *		main(*)
+	 * Method pattern are formed by:<br>
+	 * 	[declaringType '.'] ['&lt;' typeArguments '&gt;'] selector ['(' parameterTypes ')'] [returnType]
+	 *		<br>e.g.<ul>
+	 *			<li>java.lang.Runnable.run() void</li>
+	 *			<li>main(*)</li>
+	 *			<li>&lt;String&gt;toArray(String[])</li>
+	 *		</ul>
+	 * Constructor pattern are formed by:<br>
+	 *		[declaringQualification '.'] ['&lt;' typeArguments '&gt;'] type ['(' parameterTypes ')']
+	 *		<br>e.g.<ul>
+	 *			<li>java.lang.Object()</li>
+	 *			<li>Main(*)</li>
+	 *			<li>&lt;Exception&gt;Sample(Exception)</li>
+	 *		</ul>
+	 * Type arguments have the same pattern that for type patterns
+	 * @see #createTypePattern(String,int,int)
 	 */
-	private static SearchPattern createMethodPattern(String patternString, int limitTo, int matchRule) {
+	private static SearchPattern createMethodOrConstructorPattern(String patternString, int limitTo, int matchRule, boolean isConstructor) {
 		
 		Scanner scanner = new Scanner(false /*comment*/, true /*whitespace*/, false /*nls*/, ClassFileConstants.JDK1_3/*sourceLevel*/, null /*taskTags*/, null/*taskPriorities*/, true/*taskCaseSensitive*/); 
 		scanner.setSource(patternString.toCharArray());
 		final int InsideSelector = 1;
-		final int InsideParameter = 2;
-		final int InsideReturnType = 3;
+		final int InsideTypeArguments = 2;
+		final int InsideParameter = 3;
+		final int InsideReturnType = 4;
 		int lastToken = -1;
 		
 		String declaringType = null, selector = null, parameterType = null;
 		String[] parameterTypes = null;
+		char[][] typeArguments = null;
+		String typeArgumentsString = null;
 		int parameterCount = -1;
 		String returnType = null;
 		boolean foundClosingParenthesis = false;
 		int mode = InsideSelector;
-		int token;
+		int token, argCount = 0;
 		try {
 			token = scanner.getNextToken();
 		} catch (InvalidInputException e) {
@@ -512,72 +369,175 @@
 			switch(mode) {
 				// read declaring type and selector
 				case InsideSelector :
+					if (argCount == 0) {
+						switch (token) {
+							case TerminalTokens.TokenNameLESS:
+								argCount++;
+								if (selector == null || lastToken == TerminalTokens.TokenNameDOT) {
+									if (typeArgumentsString != null) return null; // invalid syntax
+									typeArgumentsString = scanner.getCurrentTokenString();
+									mode = InsideTypeArguments;
+									break;
+								}
+								if (declaringType == null) {
+									declaringType = selector;
+								} else {
+									declaringType += '.' + selector;
+								}
+								declaringType += scanner.getCurrentTokenString();
+								selector = null;
+								break;
+							case TerminalTokens.TokenNameDOT:
+								if (typeArgumentsString != null) return null; // invalid syntax
+								if (declaringType == null) {
+									if (selector == null) return null; // invalid syntax
+									declaringType = selector;
+								} else if (selector != null) {
+									declaringType += scanner.getCurrentTokenString() + selector;
+								}
+								selector = null;
+								break;
+							case TerminalTokens.TokenNameLPAREN:
+								parameterTypes = new String[5];
+								parameterCount = 0;
+								mode = InsideParameter;
+								break;
+							case TerminalTokens.TokenNameWHITESPACE:
+								switch (lastToken) {
+									case TerminalTokens.TokenNameWHITESPACE:
+									case TerminalTokens.TokenNameDOT:
+									case TerminalTokens.TokenNameGREATER:
+									case TerminalTokens.TokenNameRIGHT_SHIFT:
+									case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+										break;
+									default:
+										mode = InsideReturnType;
+										break;
+								}
+								break;
+							default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+								if (selector == null)
+									selector = scanner.getCurrentTokenString();
+								else
+									selector += scanner.getCurrentTokenString();
+								break;
+						}
+					} else {
+						if (declaringType == null) return null; // invalid syntax
+						switch (token) {
+							case TerminalTokens.TokenNameGREATER:
+							case TerminalTokens.TokenNameRIGHT_SHIFT:
+							case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+								argCount--;
+								break;
+							case TerminalTokens.TokenNameLESS:
+								argCount++;
+								break;
+						}
+						declaringType += scanner.getCurrentTokenString();
+					}
+					break;
+				// read type arguments
+				case InsideTypeArguments:
+					if (typeArgumentsString == null) return null; // invalid syntax
+					typeArgumentsString += scanner.getCurrentTokenString();
 					switch (token) {
-						case TerminalTokens.TokenNameDOT:
-							if (declaringType == null) {
-								if (selector == null) return null;
-								declaringType = selector;
-							} else {
-								String tokenSource = new String(scanner.getCurrentTokenSource());
-								declaringType += tokenSource + selector;
+						case TerminalTokens.TokenNameGREATER:
+						case TerminalTokens.TokenNameRIGHT_SHIFT:
+						case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+							argCount--;
+							if (argCount == 0) {
+								String pseudoType = "Type"+typeArgumentsString; //$NON-NLS-1$
+								typeArguments = Signature.getTypeArguments(Signature.createTypeSignature(pseudoType, false).toCharArray());
+								mode = InsideSelector;
 							}
-							selector = null;
 							break;
-						case TerminalTokens.TokenNameLPAREN:
-							parameterTypes = new String[5];
-							parameterCount = 0;
-							mode = InsideParameter;
-							break;
-						case TerminalTokens.TokenNameWHITESPACE:
-							if (!(TerminalTokens.TokenNameWHITESPACE == lastToken || TerminalTokens.TokenNameDOT == lastToken))
-								mode = InsideReturnType;
-							break;
-						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
-							if (selector == null)
-								selector = new String(scanner.getCurrentTokenSource());
-							else
-								selector += new String(scanner.getCurrentTokenSource());
+						case TerminalTokens.TokenNameLESS:
+							argCount++;
 							break;
 					}
 					break;
 				// read parameter types
 				case InsideParameter :
-					switch (token) {
-						case TerminalTokens.TokenNameWHITESPACE:
-							break;
-						case TerminalTokens.TokenNameCOMMA:
-							if (parameterType == null) return null;
-							if (parameterTypes.length == parameterCount)
-								System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
-							parameterTypes[parameterCount++] = parameterType;
-							parameterType = null;
-							break;
-						case TerminalTokens.TokenNameRPAREN:
-							foundClosingParenthesis = true;
-							if (parameterType != null){
+					if (argCount == 0) {
+						switch (token) {
+							case TerminalTokens.TokenNameWHITESPACE:
+								break;
+							case TerminalTokens.TokenNameCOMMA:
+								if (parameterType == null) return null;
 								if (parameterTypes.length == parameterCount)
 									System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
 								parameterTypes[parameterCount++] = parameterType;
-							}
-							mode = InsideReturnType;
-							break;
-						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
-							if (parameterType == null)
-								parameterType = new String(scanner.getCurrentTokenSource());
-							else
-								parameterType += new String(scanner.getCurrentTokenSource());
+								parameterType = null;
+								break;
+							case TerminalTokens.TokenNameRPAREN:
+								foundClosingParenthesis = true;
+								if (parameterType != null){
+									if (parameterTypes.length == parameterCount)
+										System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
+									parameterTypes[parameterCount++] = parameterType;
+								}
+								mode = isConstructor ? InsideTypeArguments : InsideReturnType;
+								break;
+							case TerminalTokens.TokenNameLESS:
+								argCount++;
+								if (parameterType == null) return null; // invalid syntax
+								// fall through next case to add token
+							default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+								if (parameterType == null)
+									parameterType = scanner.getCurrentTokenString();
+								else
+									parameterType += scanner.getCurrentTokenString();
+						}
+					} else {
+						if (parameterType == null) return null; // invalid syntax
+						switch (token) {
+							case TerminalTokens.TokenNameGREATER:
+							case TerminalTokens.TokenNameRIGHT_SHIFT:
+							case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+								argCount--;
+								break;
+							case TerminalTokens.TokenNameLESS:
+								argCount++;
+								break;
+						}
+						parameterType += scanner.getCurrentTokenString();
 					}
 					break;
 				// read return type
 				case InsideReturnType:
-					switch (token) {
-						case TerminalTokens.TokenNameWHITESPACE:
-							break;
-						default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
-							if (returnType == null)
-								returnType = new String(scanner.getCurrentTokenSource());
-							else
-								returnType += new String(scanner.getCurrentTokenSource());
+					if (argCount == 0) {
+						switch (token) {
+							case TerminalTokens.TokenNameWHITESPACE:
+								break;
+							case TerminalTokens.TokenNameLPAREN:
+								parameterTypes = new String[5];
+								parameterCount = 0;
+								mode = InsideParameter;
+								break;
+							case TerminalTokens.TokenNameLESS:
+								argCount++;
+								if (returnType == null) return null; // invalid syntax
+								// fall through next case to add token
+							default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+								if (returnType == null)
+									returnType = scanner.getCurrentTokenString();
+								else
+									returnType += scanner.getCurrentTokenString();
+						}
+					} else {
+						if (returnType == null) return null; // invalid syntax
+						switch (token) {
+							case TerminalTokens.TokenNameGREATER:
+							case TerminalTokens.TokenNameRIGHT_SHIFT:
+							case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+								argCount--;
+								break;
+							case TerminalTokens.TokenNameLESS:
+								argCount++;
+								break;
+						}
+						returnType += scanner.getCurrentTokenString();
 					}
 					break;
 			}
@@ -590,19 +550,48 @@
 		}
 		// parenthesis mismatch
 		if (parameterCount>0 && !foundClosingParenthesis) return null;
-		if (selector == null) return null;
-	
-		char[] selectorChars = selector.toCharArray();
-		if (selectorChars.length == 1 && selectorChars[0] == '*')
-			selectorChars = null;
+		// type arguments mismatch
+		if (argCount > 0) return null;
+
+		char[] selectorChars = null;
+		if (isConstructor) {
+			// retrieve type for constructor patterns
+			if (declaringType == null)
+				declaringType = selector;
+			else if (selector != null)
+				declaringType += '.' + selector;
+		} else {
+			// get selector chars
+			if (selector == null) return null;
+			selectorChars = selector.toCharArray();
+			if (selectorChars.length == 1 && selectorChars[0] == '*')
+				selectorChars = null;
+		}
 			
 		char[] declaringTypeQualification = null, declaringTypeSimpleName = null;
 		char[] returnTypeQualification = null, returnTypeSimpleName = null;
 		char[][] parameterTypeQualifications = null, parameterTypeSimpleNames = null;
+		// Signatures
+		String declaringTypeSignature = null;
+		String returnTypeSignature = null;
+		String[] parameterTypeSignatures = null;
 	
 		// extract declaring type infos
 		if (declaringType != null) {
-			char[] declaringTypePart = declaringType.toCharArray();
+			// get declaring type part and signature
+			char[] declaringTypePart = null;
+			try {
+				declaringTypeSignature = Signature.createTypeSignature(declaringType, false);
+				if (declaringTypeSignature.indexOf(Signature.C_GENERIC_START) < 0) {
+					declaringTypePart = declaringType.toCharArray();
+				} else {
+					declaringTypePart = Signature.toCharArray(Signature.getTypeErasure(declaringTypeSignature.toCharArray()));
+				}
+			}
+			catch (IllegalArgumentException iae) {
+				// declaring type is invalid
+				return null;
+			}
 			int lastDotPosition = CharOperation.lastIndexOf('.', declaringTypePart);
 			if (lastDotPosition >= 0) {
 				declaringTypeQualification = CharOperation.subarray(declaringTypePart, 0, lastDotPosition);
@@ -620,8 +609,22 @@
 		if (parameterCount >= 0) {
 			parameterTypeQualifications = new char[parameterCount][];
 			parameterTypeSimpleNames = new char[parameterCount][];
+			parameterTypeSignatures = new String[parameterCount];
 			for (int i = 0; i < parameterCount; i++) {
-				char[] parameterTypePart = parameterTypes[i].toCharArray();
+				// get parameter type part and signature
+				char[] parameterTypePart = null;
+				try {
+					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypes[i], false);
+					if (parameterTypeSignatures[i].indexOf(Signature.C_GENERIC_START) < 0) {
+						parameterTypePart = parameterTypes[i].toCharArray();
+					} else {
+						parameterTypePart = Signature.toCharArray(Signature.getTypeErasure(parameterTypeSignatures[i].toCharArray()));
+					}
+				}
+				catch (IllegalArgumentException iae) {
+					// string is not a valid type syntax
+					return null;
+				}
 				int lastDotPosition = CharOperation.lastIndexOf('.', parameterTypePart);
 				if (lastDotPosition >= 0) {
 					parameterTypeQualifications[i] = CharOperation.subarray(parameterTypePart, 0, lastDotPosition);
@@ -642,7 +645,20 @@
 		}	
 		// extract return type infos
 		if (returnType != null) {
-			char[] returnTypePart = returnType.toCharArray();
+			// get return type part and signature
+			char[] returnTypePart = null;
+			try {
+				returnTypeSignature = Signature.createTypeSignature(returnType, false);
+				if (returnTypeSignature.indexOf(Signature.C_GENERIC_START) < 0) {
+					returnTypePart = returnType.toCharArray();
+				} else {
+					returnTypePart = Signature.toCharArray(Signature.getTypeErasure(returnTypeSignature.toCharArray()));
+				}
+			}
+			catch (IllegalArgumentException iae) {
+				// declaring type is invalid
+				return null;
+			}
 			int lastDotPosition = CharOperation.lastIndexOf('.', returnTypePart);
 			if (lastDotPosition >= 0) {
 				returnTypeQualification = CharOperation.subarray(returnTypePart, 0, lastDotPosition);
@@ -660,52 +676,50 @@
 			if (returnTypeSimpleName.length == 1 && returnTypeSimpleName[0] == '*')
 				returnTypeSimpleName = null;
 		}
+		// Create method/constructor pattern
+		boolean findDeclarations = true;
+		boolean findReferences = true;
 		switch (limitTo) {
 			case IJavaSearchConstants.DECLARATIONS :
-				return new MethodPattern(
-					true,
-					false,
-					selectorChars, 
-					declaringTypeQualification, 
-					declaringTypeSimpleName, 
-					returnTypeQualification, 
-					returnTypeSimpleName, 
-					parameterTypeQualifications, 
-					parameterTypeSimpleNames,
-					false,
-					null,
-					matchRule);
+				findReferences = false;
+				break;
 			case IJavaSearchConstants.REFERENCES :
-				return new MethodPattern(
-					false,
-					true,
-					selectorChars, 
-					declaringTypeQualification, 
-					declaringTypeSimpleName, 
-					returnTypeQualification, 
-					returnTypeSimpleName, 
-					parameterTypeQualifications, 
-					parameterTypeSimpleNames,
-					false,
-					null,
-					matchRule);
+				findDeclarations = false;
+				break;
 			case IJavaSearchConstants.ALL_OCCURRENCES :
-				return new MethodPattern(
-					true,
-					true,
-					selectorChars, 
-					declaringTypeQualification, 
+				break;
+		}
+		if (isConstructor) {
+			return new ConstructorPattern(
+					findDeclarations,
+					findReferences,
 					declaringTypeSimpleName, 
-					returnTypeQualification, 
-					returnTypeSimpleName, 
+					declaringTypeQualification,
+					declaringTypeSignature,
 					parameterTypeQualifications, 
 					parameterTypeSimpleNames,
-					false,
-					null,
+					parameterTypeSignatures,
+					typeArguments,
+					matchRule);
+		} else {
+			return new MethodPattern(
+					findDeclarations,
+					findReferences,
+					selectorChars,
+					declaringTypeQualification,
+					declaringTypeSimpleName,
+					declaringTypeSignature,
+					returnTypeQualification,
+					returnTypeSimpleName,
+					returnTypeSignature,
+					parameterTypeQualifications,
+					parameterTypeSimpleNames,
+					parameterTypeSignatures,
+					typeArguments,
 					matchRule);
 		}
-		return null;
 	}
+
 	/**
 	 * Returns a search pattern that combines the given two patterns into an
 	 * "or" pattern. The search result will match either the left pattern or the
@@ -733,6 +747,7 @@
 		}
 		return null;
 	}
+
 	/**
 	 * Returns a search pattern based on a given string pattern. The string patterns support '*' wild-cards.
 	 * The remaining parameters are used to narrow down the type of expected results.
@@ -750,43 +765,55 @@
 	 * @param stringPattern the given pattern
 	 * @param searchFor determines the nature of the searched elements
 	 *	<ul>
-	 * 	<li><code>IJavaSearchConstants.CLASS</code>: only look for classes</li>
-	 *		<li><code>IJavaSearchConstants.INTERFACE</code>: only look for interfaces</li>
-	 * 	<li><code>IJavaSearchConstants.TYPE</code>: look for both classes and interfaces</li>
-	 *		<li><code>IJavaSearchConstants.FIELD</code>: look for fields</li>
-	 *		<li><code>IJavaSearchConstants.METHOD</code>: look for methods</li>
-	 *		<li><code>IJavaSearchConstants.CONSTRUCTOR</code>: look for constructors</li>
-	 *		<li><code>IJavaSearchConstants.PACKAGE</code>: look for packages</li>
+	 * 	<li>{@link IJavaSearchConstants#CLASS}: only look for classes</li>
+	 *		<li>{@link IJavaSearchConstants#INTERFACE}: only look for interfaces</li>
+	 * 	<li>{@link IJavaSearchConstants#TYPE}: look for both classes and interfaces</li>
+	 *		<li>{@link IJavaSearchConstants#FIELD}: look for fields</li>
+	 *		<li>{@link IJavaSearchConstants#METHOD}: look for methods</li>
+	 *		<li>{@link IJavaSearchConstants#CONSTRUCTOR}: look for constructors</li>
+	 *		<li>{@link IJavaSearchConstants#PACKAGE}: look for packages</li>
 	 *	</ul>
 	 * @param limitTo determines the nature of the expected matches
 	 *	<ul>
-	 * 		<li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding
-	 * 			element. In case the element is a method, declarations of matching methods in subtypes will also
-	 *  		be found, allowing to find declarations of abstract methods, etc.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified
-	 *  		above.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li>
+	 * 	<li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching
+	 * 			with the corresponding element. In case the element is a method, declarations of matching
+	 * 			methods in subtypes will also be found, allowing to find declarations of abstract methods, etc.<br>
+	 * 			Note that additional flags {@link IJavaSearchConstants#IGNORE_DECLARING_TYPE} and
+	 * 			{@link IJavaSearchConstants#IGNORE_RETURN_TYPE} are ignored for string patterns.
+	 * 			This is due to the fact that client may omit to define them in string pattern to have same behavior.
+	 * 	</li>
+	 *		 <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
+	 *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or
+	 *				references as specified above.
+	 *		</li>
+	 *		 <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for interface, will find all types
+	 *				which implements a given interface.
+	 *		</li>
 	 *	</ul>
-	 * @param matchRule one of R_EXACT_MATCH, R_PREFIX_MATCH, R_PATTERN_MATCH, R_REGEXP_MATCH combined with R_CASE_SENSITIVE,
-	 *   e.g. R_EXACT_MATCH | R_CASE_SENSITIVE if an exact and case sensitive match is requested, 
-	 *   or R_PREFIX_MATCH if a prefix non case sensitive match is requested.
+	 * @param matchRule one of {@link #R_EXACT_MATCH}, {@link #R_PREFIX_MATCH}, {@link #R_PATTERN_MATCH},
+	 * 	{@link #R_REGEXP_MATCH} combined with one of follwing values: {@link #R_CASE_SENSITIVE}, {@link #R_ERASURE_MATCH}
+	 * 	or {@link #R_EQUIVALENT_MATCH}.
+	 *		e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE} if an exact and case sensitive match is requested, 
+	 *		{@link #R_PREFIX_MATCH} if a prefix non case sensitive match is requested or {@link #R_EXACT_MATCH} | {@link #R_ERASURE_MATCH}
+	 *		if a non case sensitive and erasure match is requested.<br>
+	 * 	Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} have no effect
+	 * 	on non-generic types/methods search.<br>
+	 * 	Note also that default behavior for generic types/methods search is to find exact matches.
 	 * @return a search pattern on the given string pattern, or <code>null</code> if the string pattern is ill-formed
-	 * [TODO (frederic) Expand spec for matchRule to allow R_ERASURE_MATCH ?]
 	 */
 	public static SearchPattern createPattern(String stringPattern, int searchFor, int limitTo, int matchRule) {
 		if (stringPattern == null || stringPattern.length() == 0) return null;
+
+		// Ignore additional nature flags
+		limitTo &= ~(IJavaSearchConstants.IGNORE_DECLARING_TYPE+IJavaSearchConstants.IGNORE_RETURN_TYPE);
 	
 		switch (searchFor) {
 			case IJavaSearchConstants.TYPE:
 				return createTypePattern(stringPattern, limitTo, matchRule);
 			case IJavaSearchConstants.METHOD:
-				return createMethodPattern(stringPattern, limitTo, matchRule);
+				return createMethodOrConstructorPattern(stringPattern, limitTo, matchRule, false/*not a constructor*/);
 			case IJavaSearchConstants.CONSTRUCTOR:
-				return createConstructorPattern(stringPattern, limitTo, matchRule);
+				return createMethodOrConstructorPattern(stringPattern, limitTo, matchRule, true/*constructor*/);
 			case IJavaSearchConstants.FIELD:
 				return createFieldPattern(stringPattern, limitTo, matchRule);
 			case IJavaSearchConstants.PACKAGE:
@@ -801,17 +828,40 @@
 	 *
 	 * @param element the Java element the search pattern is based on
 	 * @param limitTo determines the nature of the expected matches
-	 * 	<ul>
-	 * 		<li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding
-	 * 			element. In case the element is a method, declarations of matching methods in subtypes will also
-	 *  		be found, allowing to find declarations of abstract methods, etc.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified
-	 *  		above.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li>
+	 *	<ul>
+	 * 	<li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching
+	 * 			with the corresponding element. In case the element is a method, declarations of matching
+	 * 			methods in subtypes will also be found, allowing to find declarations of abstract methods, etc.
+	 *				Some additional flags may be specified while searching declaration:
+	 *				<ul>
+	 *					<li>{@link IJavaSearchConstants#IGNORE_DECLARING_TYPE}: declaring type will be ignored
+	 *							during the search.<br>
+	 *							For example using following test case:
+	 *							<pre>
+	 *								class A { A method() { return null; } }
+	 *								class B extends A { B method() { return null; } }
+	 *								class C { A method() { return null; } }
+	 *							</pre>
+	 *							search for <code>method</code> declaration with this flag
+	 *							will return 2 matches: in A and in C
+	 *					</li>
+	 *					<li>{@link IJavaSearchConstants#IGNORE_RETURN_TYPE}: return type will be ignored
+	 *							during the search.<br>
+	 *							Using same example, search for <code>method</code> declaration with this flag
+	 *							will return 2 matches: in A and in B.
+	 *					</li>
+	 *				<ul>
+	 *				Note that these two flags may be combined and both declaring and return types can be ignored
+	 *				during the search. Then, using same example, search for <code>method</code> declaration
+	 *				with these 2 flags will return 3 matches: in A, in B  and in C
+	 * 	</li>
+	 *		 <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
+	 *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or
+	 *				references as specified above.
+	 *		</li>
+	 *		 <li>{@link IJavaSearchConstants#IMPLEMENTORS}: 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
 	 */
@@ -825,135 +875,138 @@
 	 *
 	 * @param element the Java element the search pattern is based on
 	 * @param limitTo determines the nature of the expected matches
-	 * 	<ul>
-	 * 		<li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding
-	 * 			element. In case the element is a method, declarations of matching methods in subtypes will also
-	 *  		be found, allowing to find declarations of abstract methods, etc.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified
-	 *  		above.</li>
-	 *
-	 *		 <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li>
+	 *	<ul>
+	 * 	<li>{@link IJavaSearchConstants#DECLARATIONS}: will search declarations matching
+	 * 			with the corresponding element. In case the element is a method, declarations of matching
+	 * 			methods in subtypes will also be found, allowing to find declarations of abstract methods, etc.
+	 *				Some additional flags may be specified while searching declaration:
+	 *				<ul>
+	 *					<li>{@link IJavaSearchConstants#IGNORE_DECLARING_TYPE}: declaring type will be ignored
+	 *							during the search.<br>
+	 *							For example using following test case:
+	 *							<pre>
+	 *								class A { A method() { return null; } }
+	 *								class B extends A { B method() { return null; } }
+	 *								class C { A method() { return null; } }
+	 *							</pre>
+	 *							search for <code>method</code> declaration with this flag
+	 *							will return 2 matches: in A and in C
+	 *					</li>
+	 *					<li>{@link IJavaSearchConstants#IGNORE_RETURN_TYPE}: return type will be ignored
+	 *							during the search.<br>
+	 *							Using same example, search for <code>method</code> declaration with this flag
+	 *							will return 2 matches: in A and in B.
+	 *					</li>
+	 *				<ul>
+	 *				Note that these two flags may be combined and both declaring and return types can be ignored
+	 *				during the search. Then, using same example, search for <code>method</code> declaration
+	 *				with these 2 flags will return 3 matches: in A, in B  and in C
+	 * 	</li>
+	 *		 <li>{@link IJavaSearchConstants#REFERENCES}: will search references to the given element.</li>
+	 *		 <li>{@link IJavaSearchConstants#ALL_OCCURRENCES}: will search for either declarations or
+	 *				references as specified above.
+	 *		</li>
+	 *		 <li>{@link IJavaSearchConstants#IMPLEMENTORS}: for interface, will find all types
+	 *				which implements a given interface.
+	 *		</li>
 	 *	</ul>
-	 * @param matchRule Same possible values than those described in method {@link #createPattern(String,int,int,int)} plus another possible
-	 * 	new value {@link #R_ERASURE_MATCH} which can be combined with the others. When match rule includes {@link #R_ERASURE_MATCH},
-	 * 	the search engine finds all types whose erasures match the given pattern erasure.
-	 * 	By default, the search engine only finds exact or compatible matches for generic or parameterized types.
+	 * @param matchRule one of {@link #R_EXACT_MATCH}, {@link #R_PREFIX_MATCH}, {@link #R_PATTERN_MATCH},
+	 * 	{@link #R_REGEXP_MATCH} combined with one of follwing values: {@link #R_CASE_SENSITIVE}, {@link #R_ERASURE_MATCH}
+	 * 	or {@link #R_EQUIVALENT_MATCH}.
+	 *		e.g. {@link #R_EXACT_MATCH} | {@link #R_CASE_SENSITIVE} if an exact and case sensitive match is requested, 
+	 *		{@link #R_PREFIX_MATCH} if a prefix non case sensitive match is requested or {@link #R_EXACT_MATCH} |{@link #R_ERASURE_MATCH}
+	 *		if a non case sensitive and erasure match is requested.<br>
+	 * 	Note that {@link #R_ERASURE_MATCH} or {@link #R_EQUIVALENT_MATCH} have no effect on non-generic types
+	 * 	or methods search.<br>
+	 * 	Note also that default behavior for generic types or methods is to find exact matches.
 	 * @return a search pattern for a Java element or <code>null</code> if the given element is ill-formed
 	 * @since 3.1
 	 */
 	public static SearchPattern createPattern(IJavaElement element, int limitTo, int matchRule) {
 		SearchPattern searchPattern = null;
 		int lastDot;
+		boolean ignoreDeclaringType = false;
+		boolean ignoreReturnType = false;
+		int maskedLimitTo = limitTo & ~(IJavaSearchConstants.IGNORE_DECLARING_TYPE+IJavaSearchConstants.IGNORE_RETURN_TYPE);
+		if (maskedLimitTo == IJavaSearchConstants.DECLARATIONS || maskedLimitTo == IJavaSearchConstants.ALL_OCCURRENCES) {
+			ignoreDeclaringType = (limitTo & IJavaSearchConstants.IGNORE_DECLARING_TYPE) != 0;
+			ignoreReturnType = (limitTo & IJavaSearchConstants.IGNORE_RETURN_TYPE) != 0;
+		}
+		char[] declaringSimpleName = null;
+		char[] declaringQualification = null;
 		switch (element.getElementType()) {
 			case IJavaElement.FIELD :
 				IField field = (IField) element; 
-				IType declaringClass = field.getDeclaringType();
-				char[] declaringSimpleName = declaringClass.getElementName().toCharArray();
-				char[] declaringQualification = declaringClass.getPackageFragment().getElementName().toCharArray();
-				char[][] enclosingNames = enclosingTypeNames(declaringClass);
-				if (enclosingNames.length > 0)
-					declaringQualification = CharOperation.concat(declaringQualification, CharOperation.concatWith(enclosingNames, '.'), '.');
-				char[] name = field.getElementName().toCharArray();
-				char[] typeSimpleName;
-				char[] typeQualification;
-				String typeSignature;
-				try {
-					typeSignature = field.getTypeSignature();
-					char[] signature = typeSignature.toCharArray();
-					char[] typeErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
-					if (CharOperation.indexOf(Signature.C_GENERIC_START, signature) < 0) {
-						typeSignature = null;
+				if (!ignoreDeclaringType) {
+					IType declaringClass = field.getDeclaringType();
+					declaringSimpleName = declaringClass.getElementName().toCharArray();
+					declaringQualification = declaringClass.getPackageFragment().getElementName().toCharArray();
+					char[][] enclosingNames = enclosingTypeNames(declaringClass);
+					if (enclosingNames.length > 0) {
+						declaringQualification = CharOperation.concat(declaringQualification, CharOperation.concatWith(enclosingNames, '.'), '.');
 					}
-					CharOperation.replace(typeErasure, '$', '.');
-					if ((lastDot = CharOperation.lastIndexOf('.', typeErasure)) == -1) {
-						typeSimpleName = typeErasure;
-						typeQualification = null;
-					} else {
-						typeSimpleName = CharOperation.subarray(typeErasure, lastDot + 1, typeErasure.length);
-						typeQualification = CharOperation.subarray(typeErasure, 0, lastDot);
-						if (!field.isBinary()) {
-							// prefix with a '*' as the full qualification could be bigger (because of an import)
-							CharOperation.concat(IIndexConstants.ONE_STAR, typeQualification);
-						}
-					}
-				} catch (JavaModelException e) {
-					return null;
 				}
-				switch (limitTo) {
+				char[] name = field.getElementName().toCharArray();
+				char[] typeSimpleName = null;
+				char[] typeQualification = null;
+				String typeSignature = null;
+				if (!ignoreReturnType) {
+					try {
+						typeSignature = field.getTypeSignature();
+						char[] signature = typeSignature.toCharArray();
+						char[] typeErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
+						CharOperation.replace(typeErasure, '$', '.');
+						if ((lastDot = CharOperation.lastIndexOf('.', typeErasure)) == -1) {
+							typeSimpleName = typeErasure;
+							typeQualification = null;
+						} else {
+							typeSimpleName = CharOperation.subarray(typeErasure, lastDot + 1, typeErasure.length);
+							typeQualification = CharOperation.subarray(typeErasure, 0, lastDot);
+							if (!field.isBinary()) {
+								// prefix with a '*' as the full qualification could be bigger (because of an import)
+								CharOperation.concat(IIndexConstants.ONE_STAR, typeQualification);
+							}
+						}
+					} catch (JavaModelException e) {
+						return null;
+					}
+				}
+				// Create field pattern
+				boolean findDeclarations = false;
+				boolean readAccess = false;
+				boolean writeAccess = false;
+				switch (maskedLimitTo) {
 					case IJavaSearchConstants.DECLARATIONS :
-						searchPattern = 
-							new FieldPattern(
-								true,
-								false,
-								false,
-								name, 
-								declaringQualification, 
-								declaringSimpleName, 
-								typeQualification, 
-								typeSimpleName,
-								typeSignature,
-								matchRule);
+						findDeclarations = true;
 						break;
 					case IJavaSearchConstants.REFERENCES :
-						searchPattern = 
-							new FieldPattern(
-								false,
-								true, // read access
-								true, // write access
-								name, 
-								declaringQualification, 
-								declaringSimpleName, 
-								typeQualification, 
-								typeSimpleName,
-								typeSignature,
-								matchRule);
+						readAccess = true;
+						writeAccess = true;
 						break;
 					case IJavaSearchConstants.READ_ACCESSES :
-						searchPattern = 
-							new FieldPattern(
-								false,
-								true, // read access only
-								false,
-								name, 
-								declaringQualification, 
-								declaringSimpleName, 
-								typeQualification, 
-								typeSimpleName,
-								typeSignature,
-								matchRule);
+						readAccess = true;
 						break;
 					case IJavaSearchConstants.WRITE_ACCESSES :
-						searchPattern = 
-							new FieldPattern(
-								false,
-								false,
-								true, // write access only
-								name, 
-								declaringQualification, 
-								declaringSimpleName, 
-								typeQualification, 
-								typeSimpleName,
-								typeSignature,
-								matchRule);
+						writeAccess = true;
 						break;
 					case IJavaSearchConstants.ALL_OCCURRENCES :
-						searchPattern =
-							new FieldPattern(
-								true,
-								true, // read access
-								true, // write access
-								name, 
-								declaringQualification, 
-								declaringSimpleName, 
-								typeQualification, 
-								typeSimpleName,
-								typeSignature,
-								matchRule);
+						findDeclarations = true;
+						readAccess = true;
+						writeAccess = true;
 						break;
 				}
+				searchPattern = 
+					new FieldPattern(
+						findDeclarations,
+						readAccess,
+						writeAccess,
+						name, 
+						declaringQualification, 
+						declaringSimpleName, 
+						typeQualification, 
+						typeSimpleName,
+						typeSignature,
+						matchRule);
 				break;
 			case IJavaElement.IMPORT_DECLARATION :
 				String elementName = element.getElementName();
@@ -961,68 +1014,70 @@
 				if (lastDot == -1) return null; // invalid import declaration
 				IImportDeclaration importDecl = (IImportDeclaration)element;
 				if (importDecl.isOnDemand()) {
-					searchPattern = createPackagePattern(elementName.substring(0, lastDot), limitTo, matchRule);
+					searchPattern = createPackagePattern(elementName.substring(0, lastDot), maskedLimitTo, matchRule);
 				} else {
 					searchPattern = 
 						createTypePattern(
 							elementName.substring(lastDot+1).toCharArray(),
 							elementName.substring(0, lastDot).toCharArray(),
 							null,
-							false, // does not need signature
 							null,
-							limitTo,
+							null,
+							maskedLimitTo,
 							matchRule);
 				}
 				break;
 			case IJavaElement.LOCAL_VARIABLE :
 				LocalVariable localVar = (LocalVariable) element;
-				switch (limitTo) {
+				boolean findVarDeclarations = false;
+				boolean findVarReadAccess = false;
+				boolean findVarWriteAccess = false;
+				switch (maskedLimitTo) {
 					case IJavaSearchConstants.DECLARATIONS :
-						searchPattern = 
-							new LocalVariablePattern(
-								true, // declarations
-								false, // no read access
-								false, // no write access
-								localVar,
-								matchRule);
+						findVarDeclarations = true;
 						break;
 					case IJavaSearchConstants.REFERENCES :
-						searchPattern = 
-							new LocalVariablePattern(
-								false,
-								true, // read access
-								true, // write access
-								localVar,
-								matchRule);
+						findVarReadAccess = true;
+						findVarWriteAccess = true;
 						break;
 					case IJavaSearchConstants.READ_ACCESSES :
-						searchPattern = 
-							new LocalVariablePattern(
-								false,
-								true, // read access only
-								false,
-								localVar,
-								matchRule);
+						findVarReadAccess = true;
 						break;
 					case IJavaSearchConstants.WRITE_ACCESSES :
-						searchPattern = 
-							new LocalVariablePattern(
-								false,
-								false,
-								true, // write access only
-								localVar,
-								matchRule);
+						findVarWriteAccess = true;
 						break;
 					case IJavaSearchConstants.ALL_OCCURRENCES :
-						searchPattern =
-							new LocalVariablePattern(
-								true,
-								true, // read access
-								true, // write access
-								localVar,
-								matchRule);
+						findVarDeclarations = true;
+						findVarReadAccess = true;
+						findVarWriteAccess = true;
 						break;
 				}
+				searchPattern = 
+					new LocalVariablePattern(
+						findVarDeclarations,
+						findVarReadAccess,
+						findVarWriteAccess,
+						localVar,
+						matchRule);
+				break;
+			case IJavaElement.TYPE_PARAMETER:
+				ITypeParameter typeParam = (ITypeParameter) element;
+				boolean findParamDeclarations = true;
+				boolean findParamReferences = true;
+				switch (maskedLimitTo) {
+					case IJavaSearchConstants.DECLARATIONS :
+						findParamReferences = false;
+						break;
+					case IJavaSearchConstants.REFERENCES :
+						findParamDeclarations = false;
+						break;
+				}
+				searchPattern = 
+					new TypeParameterPattern(
+						findParamDeclarations,
+						findParamReferences,
+						typeParam,
+						matchRule);
 				break;
 			case IJavaElement.METHOD :
 				IMethod method = (IMethod) element;
@@ -1032,168 +1087,130 @@
 				} catch (JavaModelException e) {
 					return null;
 				}
-				declaringClass = method.getDeclaringType();
-				declaringSimpleName = declaringClass.getElementName().toCharArray();
-				declaringQualification = declaringClass.getPackageFragment().getElementName().toCharArray();
-				enclosingNames = enclosingTypeNames(declaringClass);
-				if (enclosingNames.length > 0)
-					declaringQualification = CharOperation.concat(declaringQualification, CharOperation.concatWith(enclosingNames, '.'), '.');
-				char[] selector = method.getElementName().toCharArray();
-				char[] returnSimpleName;
-				char[] returnQualification;
-				boolean varargs = false;
-				try {
-					String returnType = Signature.toString(method.getReturnType()).replace('$', '.');
-					if ((lastDot = returnType.lastIndexOf('.')) == -1) {
-						returnSimpleName = returnType.toCharArray();
-						returnQualification = null;
-					} else {
-						returnSimpleName = returnType.substring(lastDot + 1).toCharArray();
-						returnQualification = method.isBinary()
-							? returnType.substring(0, lastDot).toCharArray()
-							// prefix with a '*' as the full qualification could be bigger (because of an import)
-							: CharOperation.concat(IIndexConstants.ONE_STAR, returnType.substring(0, lastDot).toCharArray());
+				IType declaringClass = method.getDeclaringType();
+				if (ignoreDeclaringType) {
+					if (isConstructor) declaringSimpleName = declaringClass.getElementName().toCharArray();
+				} else {
+					declaringSimpleName = declaringClass.getElementName().toCharArray();
+					declaringQualification = declaringClass.getPackageFragment().getElementName().toCharArray();
+					char[][] enclosingNames = enclosingTypeNames(declaringClass);
+					if (enclosingNames.length > 0) {
+						declaringQualification = CharOperation.concat(declaringQualification, CharOperation.concatWith(enclosingNames, '.'), '.');
 					}
-					varargs = Flags.isVarargs(method.getFlags());
-				} catch (JavaModelException e) {
-					return null;
+				}
+				char[] selector = method.getElementName().toCharArray();
+				char[] returnSimpleName = null;
+				char[] returnQualification = null;
+				String returnSignature = null;
+				if (!ignoreReturnType) {
+					try {
+						returnSignature = method.getReturnType();
+						char[] signature = returnSignature.toCharArray();
+						char[] returnErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
+						CharOperation.replace(returnErasure, '$', '.');
+						if ((lastDot = CharOperation.lastIndexOf('.', returnErasure)) == -1) {
+							returnSimpleName = returnErasure;
+							returnQualification = null;
+						} else {
+							returnSimpleName = CharOperation.subarray(returnErasure, lastDot + 1, returnErasure.length);
+							returnQualification = CharOperation.subarray(returnErasure, 0, lastDot);
+							if (!method.isBinary()) {
+								// prefix with a '*' as the full qualification could be bigger (because of an import)
+								CharOperation.concat(IIndexConstants.ONE_STAR, returnQualification);
+							}
+						}
+					} catch (JavaModelException e) {
+						return null;
+					}
 				}
 				String[] parameterTypes = method.getParameterTypes();
 				int paramCount = parameterTypes.length;
 				char[][] parameterSimpleNames = new char[paramCount][];
 				char[][] parameterQualifications = new char[paramCount][];
+				String[] parameterSignatures = new String[paramCount];
 				for (int i = 0; i < paramCount; i++) {
-					String signature = Signature.toString(parameterTypes[i]).replace('$', '.');
-					if ((lastDot = signature.lastIndexOf('.')) == -1) {
-						parameterSimpleNames[i] = signature.toCharArray();
+					parameterSignatures[i] = parameterTypes[i];
+					char[] signature = parameterSignatures[i].toCharArray();
+					char[] paramErasure = Signature.toCharArray(Signature.getTypeErasure(signature));
+					CharOperation.replace(paramErasure, '$', '.');
+					if ((lastDot = CharOperation.lastIndexOf('.', paramErasure)) == -1) {
+						parameterSimpleNames[i] = paramErasure;
 						parameterQualifications[i] = null;
 					} else {
-						parameterSimpleNames[i] = signature.substring(lastDot + 1).toCharArray();
-						parameterQualifications[i] = method.isBinary()
-							? signature.substring(0, lastDot).toCharArray()
+						parameterSimpleNames[i] = CharOperation.subarray(paramErasure, lastDot + 1, paramErasure.length);
+						parameterQualifications[i] = CharOperation.subarray(paramErasure, 0, lastDot);
+						if (!method.isBinary()) {
 							// prefix with a '*' as the full qualification could be bigger (because of an import)
-							: CharOperation.concat(IIndexConstants.ONE_STAR, signature.substring(0, lastDot).toCharArray());
+							CharOperation.concat(IIndexConstants.ONE_STAR, parameterQualifications[i]);
+						}
 					}
 				}
-				switch (limitTo) {
+
+				// Create method/constructor pattern
+				boolean findMethodDeclarations = true;
+				boolean findMethodReferences = true;
+				switch (maskedLimitTo) {
 					case IJavaSearchConstants.DECLARATIONS :
-						if (isConstructor) {
-							searchPattern = 
-								new ConstructorPattern(
-									true,
-									false,
-									declaringSimpleName, 
-									declaringQualification, 
-									parameterQualifications, 
-									parameterSimpleNames,
-									varargs,
-									matchRule);
-						} else {
-							searchPattern = 
-								new MethodPattern(
-									true,
-									false,
-									selector, 
-									declaringQualification, 
-									declaringSimpleName, 
-									returnQualification, 
-									returnSimpleName, 
-									parameterQualifications, 
-									parameterSimpleNames,
-									varargs,
-									null,
-									matchRule);
-						}
+						findMethodReferences = false;
 						break;
 					case IJavaSearchConstants.REFERENCES :
-						if (isConstructor) {
-							searchPattern = 
-								new ConstructorPattern(
-									false,
-									true,
-									declaringSimpleName, 
-									declaringQualification, 
-									parameterQualifications, 
-									parameterSimpleNames,
-									varargs,
-									matchRule);
-						} else {
-							searchPattern = 
-								new MethodPattern(
-									false,
-									true,
-									selector, 
-									declaringQualification, 
-									declaringSimpleName, 
-									returnQualification, 
-									returnSimpleName, 
-									parameterQualifications, 
-									parameterSimpleNames,
-									varargs,
-									method.getDeclaringType(),
-									matchRule);
-						}
+						findMethodDeclarations = false;
 						break;
 					case IJavaSearchConstants.ALL_OCCURRENCES :
-						if (isConstructor) {
-							searchPattern =
-								new ConstructorPattern(
-									true,
-									true,
-									declaringSimpleName, 
-									declaringQualification, 
-									parameterQualifications, 
-									parameterSimpleNames,
-									varargs,
-									matchRule);
-						} else {
-							searchPattern =
-								new MethodPattern(
-									true,
-									true,
-									selector, 
-									declaringQualification, 
-									declaringSimpleName, 
-									returnQualification, 
-									returnSimpleName, 
-									parameterQualifications, 
-									parameterSimpleNames,
-									varargs,
-									method.getDeclaringType(),
-									matchRule);
-						}
 						break;
 				}
+				if (isConstructor) {
+					searchPattern =
+						new ConstructorPattern(
+							findMethodDeclarations,
+							findMethodReferences,
+							declaringSimpleName, 
+							declaringQualification, 
+							parameterQualifications, 
+							parameterSimpleNames,
+							parameterSignatures,
+							method,
+							matchRule);
+				} else {
+					searchPattern =
+						new MethodPattern(
+							findMethodDeclarations,
+							findMethodReferences,
+							selector, 
+							declaringQualification, 
+							declaringSimpleName, 
+							returnQualification, 
+							returnSimpleName, 
+							returnSignature,
+							parameterQualifications, 
+							parameterSimpleNames,
+							parameterSignatures,
+							method,
+							matchRule);
+				}
 				break;
 			case IJavaElement.TYPE :
 				IType type = (IType)element;
-				String signature = type instanceof ParameterizedSourceType ? ((ParameterizedSourceType) type).uniqueKey : null;
 				searchPattern = 	createTypePattern(
 							type.getElementName().toCharArray(), 
 							type.getPackageFragment().getElementName().toCharArray(),
-							enclosingTypeNames(type),
-							true, // need signature
-							signature,
-							limitTo,
+							ignoreDeclaringType ? null : enclosingTypeNames(type),
+							null,
+							type,
+							maskedLimitTo,
 							matchRule);
-				if (searchPattern == null) { // TODO (frederic) remove when new API IType.getParameterizedName() will be available
-					searchPattern = new TypeReferencePattern(
-						CharOperation.concatWith(type.getPackageFragment().getElementName().toCharArray(), enclosingTypeNames(type), '.'), 
-						type.getElementName().toCharArray(),
-						type,
-						matchRule);
-				}
 				break;
 			case IJavaElement.PACKAGE_DECLARATION :
 			case IJavaElement.PACKAGE_FRAGMENT :
-				searchPattern = createPackagePattern(element.getElementName(), limitTo, matchRule);
+				searchPattern = createPackagePattern(element.getElementName(), maskedLimitTo, matchRule);
 				break;
 		}
 		if (searchPattern != null)
 			MatchLocator.setFocus(searchPattern, element);
 		return searchPattern;
 	}
-	private static SearchPattern createTypePattern(char[] simpleName, char[] packageName, char[][] enclosingTypeNames, boolean needSignature, String typeSignature, int limitTo, int matchRule) {
+
+	private static SearchPattern createTypePattern(char[] simpleName, char[] packageName, char[][] enclosingTypeNames, String typeSignature, IType type, int limitTo, int matchRule) {
 		switch (limitTo) {
 			case IJavaSearchConstants.DECLARATIONS :
 				return new TypeDeclarationPattern(
@@ -1203,7 +1220,13 @@
 					IIndexConstants.TYPE_SUFFIX,
 					matchRule);
 			case IJavaSearchConstants.REFERENCES :
-				if (needSignature && typeSignature == null) return null;
+				if (type != null) {
+					return new TypeReferencePattern(
+						CharOperation.concatWith(packageName, enclosingTypeNames, '.'), 
+						simpleName,
+						type,
+						matchRule);
+				}
 				return new TypeReferencePattern(
 					CharOperation.concatWith(packageName, enclosingTypeNames, '.'), 
 					simpleName,
@@ -1223,29 +1246,33 @@
 						simpleName, 
 						IIndexConstants.TYPE_SUFFIX,
 						matchRule), 
-					new TypeReferencePattern(
-						CharOperation.concatWith(packageName, enclosingTypeNames, '.'), 
-						simpleName,
-						typeSignature,
-						matchRule));
+					(type != null)
+						? new TypeReferencePattern(
+							CharOperation.concatWith(packageName, enclosingTypeNames, '.'), 
+							simpleName,
+							type,
+							matchRule)
+						: new TypeReferencePattern(
+							CharOperation.concatWith(packageName, enclosingTypeNames, '.'), 
+							simpleName,
+							typeSignature,
+							matchRule)
+				);
 		}
 		return null;
 	}
 	/**
-	 * Type pattern are formed by [qualification.]type.
+	 * Type pattern are formed by [qualification '.']type [typeArguments].
 	 * e.g. java.lang.Object
 	 *		Runnable
+	 *		List<String>
 	 *
 	 * @since 3.1
 	 *		Type arguments can be specified to search references to parameterized types.
-	 * 	Then patterns will look as follow:
-	 * 		[qualification.] type [ '<' [ [ '?' {'extends'|'super'} ] type ( ',' [ '?' {'extends'|'super'} ] type )* ] '>' ]
+	 * 	and look as follow: '<' { [ '?' {'extends'|'super'} ] type ( ',' [ '?' {'extends'|'super'} ] type )* | '?' } '>'
 	 * 	Please note that:
 	 * 		- '*' is not valid inside type arguments definition <>
 	 * 		- '?' is treated as a wildcard when it is inside <> (ie. it must be put on first position of the type argument)
-	 * 		- nested <> are not allowed; List<List<Object>> will be treated as pattern List<List>
-	 * 		- only one type arguments definition is allowed; Gen<Exception>.Member<Object>
-	 *				will be treated as pattern Gen<Exception>.Member
 	 */
 	private static SearchPattern createTypePattern(String patternString, int limitTo, int matchRule) {
 		
@@ -1258,27 +1285,34 @@
 		} catch (InvalidInputException e) {
 			return null;
 		}
-		int paramCount = 0;
+		int argCount = 0;
 		while (token != TerminalTokens.TokenNameEOF) {
-			switch (token) {
-				case TerminalTokens.TokenNameWHITESPACE:
-					if (paramCount == 0) break;
-					// fall through default case if we're inside a type argument...
-				default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
-					switch (token) {
-						case TerminalTokens.TokenNameGREATER:
-						case TerminalTokens.TokenNameRIGHT_SHIFT:
-						case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
-							paramCount--;
-							break;
-						case TerminalTokens.TokenNameLESS:
-							paramCount++;
-							break;
-					}
-					if (type == null)
-						type = new String(scanner.getCurrentTokenSource());
-					else
-						type += new String(scanner.getCurrentTokenSource());
+			if (argCount == 0) {
+				switch (token) {
+					case TerminalTokens.TokenNameWHITESPACE:
+						break;
+					case TerminalTokens.TokenNameLESS:
+						argCount++;
+						// fall through default case to add token to type
+					default: // all other tokens are considered identifiers (see bug 21763 Problem in Java search [search])
+						if (type == null)
+							type = scanner.getCurrentTokenString();
+						else
+							type += scanner.getCurrentTokenString();
+				}
+			} else {
+				switch (token) {
+					case TerminalTokens.TokenNameGREATER:
+					case TerminalTokens.TokenNameRIGHT_SHIFT:
+					case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT:
+						argCount--;
+						break;
+					case TerminalTokens.TokenNameLESS:
+						argCount++;
+						break;
+				}
+				if (type == null) return null; // invalid syntax
+				type += scanner.getCurrentTokenString();
 			}
 			try {
 				token = scanner.getNextToken();
@@ -1466,6 +1500,7 @@
 						- (isRawMatch ? R_ERASURE_MATCH : 0);
 			switch (matchMode) {
 				case R_EXACT_MATCH :
+				case R_FULL_MATCH :
 					return CharOperation.equals(pattern, name, isCaseSensitive);
 				case R_PREFIX_MATCH :
 					return CharOperation.prefixEquals(pattern, name, isCaseSensitive);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java
index 85a79ca..fad5d30 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/SearchRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java
index 0b69db4..5d6051b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeDeclarationMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameRequestor.java
new file mode 100644
index 0000000..7594ca0
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeNameRequestor.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+/**
+ * A <code>TypeNameRequestor</code> collects search results from a <code>searchAllTypeNames</code>
+ * query to a <code>SearchEngine</code>. Clients must subclass this abstract class and pass
+ * an instance to the <code>SearchEngine.searchAllTypeNames(...)</code> method. Only top-level and
+ * member types are reported. Local types are not reported.
+ * <p>
+ * This class may be subclassed by clients.
+ * </p>
+ * @since 3.1
+ */
+public abstract class TypeNameRequestor {
+	/**
+	 * Accepts a top-level or a member type.
+	 * <p>
+	 * The default implementation of this method does nothing.
+	 * Subclasses should override.
+	 * </p>
+	 *
+	 * @param modifiers the modifier flags of the type. Note that for source type,
+	 *		these flags may slightly differ from thoses get after resolution.
+	 *		For example an interface defined by <code>interface A {}</code>,
+	 *		although obviously public, will be returned false by <code>Flags.isPublic(modifiers)</code>
+	 *		due to the fact that its declaration does not explicitely define public flag.
+	 *		@see org.eclipse.jdt.core.Flags
+	 * @param packageName the dot-separated name of the package of the type
+	 * @param simpleTypeName the simple name of the type
+	 * @param enclosingTypeNames if the type is a member type, 
+	 *          the simple names of the enclosing types from the outer-most to the
+	 *          direct parent of the type (for example, if the class is x.y.A$B$C then
+	 *          the enclosing types are [A, B]. This is an empty array if the type
+	 *          is a top-level type.
+	 * @param path the full path to the resource containing the type. If the resource is a .class file
+	 *          or a .java file, this is the full path in the workspace to this resource. If the
+	 *          resource is an archive (that is, a .zip or .jar file), the path is composed of 2 paths separated
+	 *		 	 by <code>IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR</code>: 
+	 *			 the first path is the full OS path to the archive (if it is an external archive), 
+	 *			 or the workspace relative <code>IPath</code> to the archive (if it is an internal archive), 
+	 * 		 the second path is the path to the resource inside the archive.
+	 */
+	public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
+		// do nothing
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterDeclarationMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterDeclarationMatch.java
new file mode 100644
index 0000000..f235e8b
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterDeclarationMatch.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a type parameter declaration or reference.
+ * The element is an {@link org.eclipse.jdt.core.ITypeParameter}.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ * 
+ * @since 3.1
+ */
+public class TypeParameterDeclarationMatch extends SearchMatch {
+
+	/**
+	 * Creates a new type parameter match.
+	 * 
+	 * @param element the type parameter
+	 * @param accuracy one of A_ACCURATE or A_INACCURATE
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public TypeParameterDeclarationMatch(IJavaElement element, int accuracy, int offset, int length, SearchParticipant participant, IResource resource) {
+		super(element, accuracy, offset, length, participant, resource);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterReferenceMatch.java
new file mode 100644
index 0000000..04b3aa1
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeParameterReferenceMatch.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.search;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * A Java search match that represents a type parameter declaration or reference.
+ * The element is the inner-most enclosing member that references this type parameter.
+ * <p>
+ * This class is intended to be instantiated and subclassed by clients.
+ * </p>
+ * 
+ * @since 3.1
+ */
+public class TypeParameterReferenceMatch extends SearchMatch {
+
+	/**
+	 * Creates a new field reference match.
+	 * 
+	 * @param enclosingElement the inner-most enclosing member that references this field
+	 * @param accuracy one of {@link #A_ACCURATE} or {@link #A_INACCURATE}
+	 * @param offset the offset the match starts at, or -1 if unknown
+	 * @param length the length of the match, or -1 if unknown
+	 * @param insideDocComment <code>true</code> if this search match is inside a doc
+	 * comment, and <code>false</code> otherwise
+	 * @param participant the search participant that created the match
+	 * @param resource the resource of the element
+	 */
+	public TypeParameterReferenceMatch(IJavaElement enclosingElement, int accuracy, int offset, int length, boolean insideDocComment, SearchParticipant participant, IResource resource) {
+		super(enclosingElement, accuracy, offset, length, participant, resource);
+		setInsideDocComment(insideDocComment);
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java
index 82a7f56..bed49a2 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/core/search/TypeReferenceMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
index 0934384..23cbcd7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -27,13 +27,15 @@
 private int sizeOfLastChunk;
 private int[] chunkOffsets;
 private int documentReferenceSize; // 1, 2 or more bytes... depends on # of document names
+private int startOfCategoryTables;
 private HashtableOfIntValues categoryOffsets;
 
 private int cacheUserCount;
 private String[][] cachedChunks; // decompressed chunks of document names
 private HashtableOfObject categoryTables; // category name -> HashtableOfObject(words -> int[] of document #'s) or offset if not read yet
+private char[] cachedCategoryName;
 
-public static final String SIGNATURE= "INDEX VERSION 1.011"; //$NON-NLS-1$
+public static final String SIGNATURE= "INDEX VERSION 1.100"; //$NON-NLS-1$
 public static boolean DEBUG = false;
 
 private static final int RE_INDEXED = -1;
@@ -78,6 +80,7 @@
 	this.cacheUserCount = -1;
 	this.cachedChunks = null;
 	this.categoryTables = null;
+	this.cachedCategoryName = null;
 	this.categoryOffsets = null;
 }
 SimpleSet addDocumentNames(String substring, MemoryIndex memoryIndex) throws IOException {
@@ -112,8 +115,10 @@
 	}
 	return results;
 }
-private void addQueryResult(HashtableOfObject results, char[] word, HashtableOfObject wordsToDocNumbers, MemoryIndex memoryIndex) throws IOException {
+private HashtableOfObject addQueryResult(HashtableOfObject results, char[] word, HashtableOfObject wordsToDocNumbers, MemoryIndex memoryIndex) throws IOException {
 	// must skip over documents which have been added/changed/deleted in the memory index
+	if (results == null)
+		results = new HashtableOfObject(13);
 	EntryResult result = (EntryResult) results.get(word);
 	if (memoryIndex == null) {
 		if (result == null)
@@ -133,18 +138,32 @@
 		if (!result.isEmpty())
 			results.put(word, result);
 	}
+	return results;
 }
 HashtableOfObject addQueryResults(char[][] categories, char[] key, int matchRule, MemoryIndex memoryIndex) throws IOException {
 	// assumes sender has called startQuery() & will call stopQuery() when finished
-	HashtableOfObject results = new HashtableOfObject(13);
-	if (this.categoryOffsets == null)
-		return results; // file is empty
+	if (this.categoryOffsets == null) return null; // file is empty
 
-	if (matchRule == SearchPattern.R_EXACT_MATCH + SearchPattern.R_CASE_SENSITIVE) {
+	HashtableOfObject results = null; // initialized if needed
+	if (key == null) {
+		for (int i = 0, l = categories.length; i < l; i++) {
+			HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], true); // cache if key is null since its a definite match
+			if (wordsToDocNumbers != null) {
+				char[][] words = wordsToDocNumbers.keyTable;
+				if (results == null)
+					results = new HashtableOfObject(wordsToDocNumbers.elementSize);
+				for (int j = 0, m = words.length; j < m; j++)
+					if (words[j] != null)
+						results = addQueryResult(results, words[j], wordsToDocNumbers, memoryIndex);
+			}
+		}
+		if (results != null && this.cachedChunks == null)
+			cacheDocumentNames();
+	} else if (matchRule == SearchPattern.R_EXACT_MATCH + SearchPattern.R_CASE_SENSITIVE) {
 		for (int i = 0, l = categories.length; i < l; i++) {
 			HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], false);
 			if (wordsToDocNumbers != null && wordsToDocNumbers.containsKey(key))
-				addQueryResult(results, key, wordsToDocNumbers, memoryIndex);
+				results = addQueryResult(results, key, wordsToDocNumbers, memoryIndex);
 		}
 	} else {
 		for (int i = 0, l = categories.length; i < l; i++) {
@@ -154,13 +173,29 @@
 				for (int j = 0, m = words.length; j < m; j++) {
 					char[] word = words[j];
 					if (word != null && Index.isMatch(key, word, matchRule))
-						addQueryResult(results, word, wordsToDocNumbers, memoryIndex);
+						results = addQueryResult(results, word, wordsToDocNumbers, memoryIndex);
 				}
 			}
 		}
 	}
+
+	if (results == null) return null;
 	return results;
 }
+private void cacheDocumentNames() throws IOException {
+	// will need all document names so get them now
+	this.cachedChunks = new String[this.numberOfChunks][];
+	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), this.numberOfChunks > 5 ? 4096 : 2048));
+	try {
+		stream.skip(this.chunkOffsets[0]);
+		for (int i = 0; i < this.numberOfChunks; i++) {
+			int size = i == this.numberOfChunks - 1 ? this.sizeOfLastChunk : CHUNK_SIZE;
+			readChunk(this.cachedChunks[i] = new String[size], stream, 0, size);
+		}
+	} finally {
+		stream.close();
+	}
+}
 private String[] computeDocumentNames(String[] onDiskNames, int[] positions, SimpleLookupTable indexedDocuments, MemoryIndex memoryIndex) {
 	int onDiskLength = onDiskNames.length;
 	Object[] docNames = memoryIndex.docsToReferences.keyTable;
@@ -294,7 +329,7 @@
 			try {
 				String signature = file.readUTF();
 				if (!signature.equals(SIGNATURE))
-					throw new IOException(Util.bind("exception.wrongFormat")); //$NON-NLS-1$
+					throw new IOException(Messages.exception_wrongFormat); 
 
 				this.headerInfoOffset = file.readInt();
 				if (this.headerInfoOffset > 0) // file is empty if its not set
@@ -477,7 +512,7 @@
 	if (this.numberOfChunks <= 0)
 		return new String[0];
 
-	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
+	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), this.numberOfChunks > 5 ? 4096 : 2048));
 	try {
 		stream.skip(this.chunkOffsets[0]);
 		int lastIndex = this.numberOfChunks - 1;
@@ -489,18 +524,25 @@
 		stream.close();
 	}
 }
-private synchronized HashtableOfObject readCategoryTable(char[] categoryName, boolean cacheDocNumbers) throws IOException {
+private synchronized HashtableOfObject readCategoryTable(char[] categoryName, boolean readDocNumbers) throws IOException {
 	// result will be null if categoryName is unknown
 	int offset = this.categoryOffsets.get(categoryName);
 	if (offset == HashtableOfIntValues.NO_VALUE)
 		return null;
 
 	if (this.categoryTables == null) {
-		this.categoryTables = new HashtableOfObject(this.categoryOffsets.elementSize);
+		this.categoryTables = new HashtableOfObject(3);
 	} else {
 		HashtableOfObject cachedTable = (HashtableOfObject) this.categoryTables.get(categoryName);
-		if (cachedTable != null)
+		if (cachedTable != null) {
+			if (readDocNumbers) { // must cache remaining document number arrays
+				Object[] arrayOffsets = cachedTable.valueTable;
+				for (int i = 0, l = arrayOffsets.length; i < l; i++)
+					if (arrayOffsets[i] instanceof Integer)
+						arrayOffsets[i] = readDocumentNumbers(arrayOffsets[i]);
+			}
 			return cachedTable;
+		}
 	}
 
 	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
@@ -512,23 +554,34 @@
 		stream.skip(offset);
 		int size = stream.readInt();
 		categoryTable = new HashtableOfObject(size);
-		if (cacheDocNumbers)
-			matchingWords = new char[size][];
+		int largeArraySize = 256;
 		for (int i = 0; i < size; i++) {
 			char[] word = Util.readUTF(stream);
 			int arrayOffset = stream.readInt();
-			if (arrayOffset > 0) {
-				if (matchingWords != null) {
+			// if arrayOffset is:
+			//		<= 0 then the array size == 1 with the value -> -arrayOffset
+			//		> 1 & < 256 then the size of the array is > 1 & < 256, the document array follows immediately
+			//		256 if the array size >= 256 followed by another int which is the offset to the array (written prior to the table)
+			if (arrayOffset <= 0) {
+				categoryTable.put(word, new int[] {-arrayOffset}); // store 1 element array by negating documentNumber
+			} else if (arrayOffset < largeArraySize) {
+				categoryTable.put(word, readDocumentArray(stream, arrayOffset)); // read in-lined array providing size
+			} else {
+				arrayOffset = stream.readInt(); // read actual offset
+				if (readDocNumbers) {
+					if (matchingWords == null)
+						matchingWords = new char[size][];
 					if (count == 0)
 						firstOffset = arrayOffset;
 					matchingWords[count++] = word;
 				}
 				categoryTable.put(word, new Integer(arrayOffset)); // offset to array in the file
-			} else {
-				categoryTable.put(word, new int[] {-arrayOffset}); // stored a 1 element array by negating the documentNumber
 			}
 		}
 		this.categoryTables.put(categoryName, categoryTable);
+		// cache the table as long as its not too big
+		// in practise, some tables can be greater than 500K when the contain more than 10K elements
+		this.cachedCategoryName = categoryTable.elementSize < 10000 ? categoryName : null;
 	} finally {
 		stream.close();
 	}
@@ -538,7 +591,7 @@
 		try {
 			stream.skip(firstOffset);
 			for (int i = 0; i < count; i++) // each array follows the previous one
-				categoryTable.put(matchingWords[i], readDocumentArray(stream));
+				categoryTable.put(matchingWords[i], readDocumentArray(stream, stream.readInt()));
 		} finally {
 			stream.close();
 		}
@@ -567,23 +620,21 @@
 		current = next;
 	}
 }
-private int[] readDocumentArray(DataInputStream stream) throws IOException {
-	int arraySize = stream.readShort();
-	if (arraySize == 0x7FFF)
-		arraySize = stream.readInt();
+private int[] readDocumentArray(DataInputStream stream, int arraySize) throws IOException {
 	int[] result = new int[arraySize];
-	for (int i = 0; i < arraySize; i++) {
-		switch (this.documentReferenceSize) {
-			case 1 :
+	switch (this.documentReferenceSize) {
+		case 1 :
+			for (int i = 0; i < arraySize; i++)
 				result[i] = stream.readUnsignedByte();
-				break;
-			case 2 :
+			break;
+		case 2 :
+			for (int i = 0; i < arraySize; i++)
 				result[i] = stream.readUnsignedShort();
-				break;
-			default :
+			break;
+		default :
+			for (int i = 0; i < arraySize; i++)
 				result[i] = stream.readInt();
-				break;
-		}
+			break;
 	}
 	return result;
 }
@@ -594,16 +645,24 @@
 	int chunkNumber = docNumber / CHUNK_SIZE;
 	String[] chunk = this.cachedChunks[chunkNumber];
 	if (chunk == null) {
-		DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
+		boolean isLastChunk = chunkNumber == this.numberOfChunks - 1;
+		int start = this.chunkOffsets[chunkNumber];
+		int numberOfBytes = (isLastChunk ? this.startOfCategoryTables : this.chunkOffsets[chunkNumber + 1]) - start;
+		if (numberOfBytes < 0)
+			throw new IllegalArgumentException();
+		byte[] bytes = new byte[numberOfBytes];
+		FileInputStream file = new FileInputStream(getIndexFile());
 		try {
-			stream.skip(this.chunkOffsets[chunkNumber]);
-			int size = chunkNumber == this.numberOfChunks - 1 ? this.sizeOfLastChunk : CHUNK_SIZE;
-			chunk = new String[size];
-			readChunk(chunk, stream, 0, size);
+			file.skip(start);
+			if (file.read(bytes, 0, numberOfBytes) != numberOfBytes)
+				throw new IOException();
 		} finally {
-			stream.close();
+			file.close();
 		}
-		this.cachedChunks[chunkNumber] = chunk;
+		DataInputStream stream = new DataInputStream(new ByteArrayInputStream(bytes));
+		int numberOfNames = isLastChunk ? this.sizeOfLastChunk : CHUNK_SIZE;
+		chunk = this.cachedChunks[chunkNumber] = new String[numberOfNames];
+		readChunk(chunk, stream, 0, numberOfNames);
 	}
 	return chunk[docNumber - (chunkNumber * CHUNK_SIZE)];
 }
@@ -615,7 +674,7 @@
 	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
 	try {
 		stream.skip(((Integer) arrayOffset).intValue());
-		return readDocumentArray(stream);
+		return readDocumentArray(stream, stream.readInt());
 	} finally {
 		stream.close();
 	}
@@ -632,11 +691,13 @@
 	for (int i = 0; i < this.numberOfChunks; i++)
 		this.chunkOffsets[i] = file.readInt();
 
+	this.startOfCategoryTables = file.readInt();
+
 	int size = file.readInt();
 	this.categoryOffsets = new HashtableOfIntValues(size);
 	for (int i = 0; i < size; i++)
 		this.categoryOffsets.put(Util.readUTF(file), file.readInt()); // cache offset to category table
-	this.categoryTables = new HashtableOfObject(size);
+	this.categoryTables = new HashtableOfObject(3);
 }
 synchronized void startQuery() {
 	this.cacheUserCount++;
@@ -646,7 +707,15 @@
 		// clear cached items
 		this.cacheUserCount = -1;
 		this.cachedChunks = null;
-		this.categoryTables = null;
+		if (this.categoryTables != null) {
+			if (this.cachedCategoryName == null) {
+				this.categoryTables = null;
+			} else if (this.categoryTables.elementSize > 1) {
+				HashtableOfObject newTables = new HashtableOfObject(3);
+				newTables.put(this.cachedCategoryName, this.categoryTables.get(this.cachedCategoryName));
+				this.categoryTables = newTables;
+			}
+		}
 	}
 }
 private void writeAllDocumentNames(String[] sortedDocNames, DataOutputStream stream) throws IOException {
@@ -693,6 +762,7 @@
 			while (current.charAt(--len1) == next.charAt(--len2)) {
 				end++;
 				if (len2 == start) break; // current is 'abbba', next is 'abba'
+				if (len1 == 0) break; // current is 'xabc', next is 'xyabc'
 			}
 			if (end > 255) end = 255;
 			stream.writeByte(start);
@@ -703,6 +773,7 @@
 			current = next;
 		}
 	}
+	this.startOfCategoryTables = stream.size() + 1;
 }
 private void writeCategories(DataOutputStream stream) throws IOException {
 	char[][] categoryNames = this.categoryTables.keyTable;
@@ -713,57 +784,68 @@
 	this.categoryTables = null;
 }
 private void writeCategoryTable(char[] categoryName, HashtableOfObject wordsToDocs, DataOutputStream stream) throws IOException {
-	// append the file with the document number arrays & remember the offsets
+	// the format of a category table is as follows:
+	// any document number arrays with >= 256 elements are written before the table (the offset to each array is remembered)
+	// then the number of word->int[] pairs in the table is written
+	// for each word -> int[] pair, the word is written followed by:
+	//		an int <= 0 if the array size == 1
+	//		an int > 1 & < 256 for the size of the array if its > 1 & < 256, the document array follows immediately
+	//		256 if the array size >= 256 followed by another int which is the offset to the array (written prior to the table)
+
+	int largeArraySize = 256;
 	Object[] values = wordsToDocs.valueTable;
 	for (int i = 0, l = values.length; i < l; i++) {
 		Object o = values[i];
 		if (o != null) {
-			int[] documentNumbers = o instanceof int[] ? (int[]) o : ((IntList) o).asArray();
-			int length = documentNumbers.length;
-			if (length == 1) {
-				values[i] = new Integer(-documentNumbers[0]); // store an array of 1 element by negating the documentNumber (can be zero)
-			} else {
+			if (o instanceof IntList)
+				o = values[i] = ((IntList) values[i]).asArray();
+			int[] documentNumbers = (int[]) o;
+			if (documentNumbers.length >= largeArraySize) {
 				values[i] = new Integer(stream.size());
 				writeDocumentNumbers(documentNumbers, stream);
 			}
 		}
 	}
 
-	// append the file with the arrays followed by the words & offsets
 	this.categoryOffsets.put(categoryName, stream.size()); // remember the offset to the start of the table
 	this.categoryTables.put(categoryName, null); // flush cached table
 	stream.writeInt(wordsToDocs.elementSize);
 	char[][] words = wordsToDocs.keyTable;
 	for (int i = 0, l = words.length; i < l; i++) {
-		if (words[i] != null) {
+		Object o = values[i];
+		if (o != null) {
 			Util.writeUTF(stream, words[i]);
-			stream.writeInt(((Integer) values[i]).intValue()); // offset in the file of the array of document numbers
+			if (o instanceof int[]) {
+				int[] documentNumbers = (int[]) o;
+				if (documentNumbers.length == 1)
+					stream.writeInt(-documentNumbers[0]); // store an array of 1 element by negating the documentNumber (can be zero)
+				else
+					writeDocumentNumbers(documentNumbers, stream);
+			} else {
+				stream.writeInt(largeArraySize); // mark to identify that an offset follows
+				stream.writeInt(((Integer) o).intValue()); // offset in the file of the array of document numbers
+			}
 		}
 	}
 }
 private void writeDocumentNumbers(int[] documentNumbers, DataOutputStream stream) throws IOException {
+	// must store length as a positive int to detect in-lined array of 1 element
 	int length = documentNumbers.length;
-	if (length < 0x7FFF) {
-		if (length == 0)
-			throw new IllegalArgumentException();
-		stream.writeShort(length);
-	} else {
-		stream.writeShort(0x7FFF);
-		stream.writeInt(length);
-	}
+	stream.writeInt(length);
 	Util.sort(documentNumbers);
-	for (int i = 0; i < length; i++) {
-		switch (this.documentReferenceSize) {
-			case 1 :
+	switch (this.documentReferenceSize) {
+		case 1 :
+			for (int i = 0; i < length; i++)
 				stream.writeByte(documentNumbers[i]);
-				break;
-			case 2 :
+			break;
+		case 2 :
+			for (int i = 0; i < length; i++)
 				stream.writeShort(documentNumbers[i]);
-				break;
-			default :
+			break;
+		default :
+			for (int i = 0; i < length; i++)
 				stream.writeInt(documentNumbers[i]);
-				break;
-		}
+			break;
 	}
 }
 private void writeHeaderInfo(DataOutputStream stream) throws IOException {
@@ -775,6 +857,8 @@
 	for (int i = 0; i < this.numberOfChunks; i++)
 		stream.writeInt(this.chunkOffsets[i]);
 
+	stream.writeInt(this.startOfCategoryTables);
+
 	// append the file with the category offsets... # of name -> offset pairs, followed by each name & an offset to its word->doc# table
 	stream.writeInt(this.categoryOffsets.elementSize);
 	char[][] categoryNames = this.categoryOffsets.keyTable;
@@ -798,4 +882,4 @@
 		}
 	}
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java
index 2d271f7..5bd3292 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -30,21 +30,30 @@
 	this.documentNames.add(documentName);
 }
 public void addDocumentTable(HashtableOfObject table) {
-	if (this.documentTables == null) {
+	if (this.documentTables != null) {
+		int length = this.documentTables.length;
+		System.arraycopy(this.documentTables, 0, this.documentTables = new HashtableOfObject[length + 1], 0, length);
+		this.documentTables[length] = table;
+	} else {
 		this.documentTables = new HashtableOfObject[] {table};
-		return;
 	}
-
-	int length = this.documentTables.length;
-	System.arraycopy(this.documentTables, 0, this.documentTables = new HashtableOfObject[length + 1], 0, length);
-	this.documentTables[length] = table;
 }
 public char[] getWord() {
 	return this.word;
 }
 public String[] getDocumentNames(Index index) throws java.io.IOException {
 	if (this.documentTables != null) {
-		for (int i = 0, l = this.documentTables.length; i < l; i++) {
+		int length = this.documentTables.length;
+		if (length == 1 && this.documentNames == null) { // have a single table
+			Object offset = this.documentTables[0].get(word);
+			int[] numbers = index.diskIndex.readDocumentNumbers(offset);
+			String[] names = new String[numbers.length];
+			for (int i = 0, l = numbers.length; i < l; i++)
+				names[i] = index.diskIndex.readDocumentName(numbers[i]);
+			return names;
+		}
+
+		for (int i = 0; i < length; i++) {
 			Object offset = this.documentTables[i].get(word);
 			int[] numbers = index.diskIndex.readDocumentNumbers(offset);
 			for (int j = 0, k = numbers.length; j < k; j++)
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
index a3132fe..118f2c5 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/Index.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,14 +12,11 @@
 
 import java.io.*;
 
-import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.*;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 import org.eclipse.jdt.internal.core.util.*;
-import org.eclipse.jdt.internal.core.search.indexing.InternalSearchDocument;
 import org.eclipse.jdt.internal.core.search.indexing.ReadWriteMonitor;
-import org.eclipse.jdt.internal.core.search.matching.JavaSearchPattern;
 
 /**
  * An <code>Index</code> maps document names to their referenced words in various categories.
@@ -31,47 +28,26 @@
 
 public class Index {
 
-public String printableName;
+public String containerPath;
 public ReadWriteMonitor monitor;
 
 protected DiskIndex diskIndex;
 protected MemoryIndex memoryIndex;
 
 /**
- * Returns the path represented by pathString converted back to a path relative to the local file system.
- *
- * @param pathString the path to convert:
- * <ul>
- *		<li>an absolute IPath (relative to the workspace root) if the path represents a resource in the 
- *			workspace
- *		<li>a relative IPath (relative to the workspace root) followed by JAR_FILE_ENTRY_SEPARATOR
- *			followed by an absolute path (relative to the jar) if the path represents a .class file in
- *			an internal jar
- *		<li>an absolute path (relative to the file system) followed by JAR_FILE_ENTRY_SEPARATOR
- *			followed by an absolute path (relative to the jar) if the path represents a .class file in
- *			an external jar
- * </ul>
- * @return the converted path:
- * <ul>
- *		<li>the original pathString if the path represents a resource in the workspace
- *		<li>an absolute path (relative to the file system) followed by JAR_FILE_ENTRY_SEPARATOR
- *			followed by an absolute path (relative to the jar) if the path represents a .class file in
- *			an external or internal jar
- * </ul>
+ * Mask used on match rule for indexing.
  */
-public static String convertPath(String pathString) {
-	int index = pathString.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
-	if (index == -1) return pathString;
-	
-	Path jarPath = new Path(pathString.substring(0, index));
-	return (jarPath.isAbsolute() ? jarPath.toOSString() : jarPath.makeAbsolute().toString())
-		+ pathString.substring(index, pathString.length());
-}
+static final int MATCH_RULE_INDEX_MASK = SearchPattern.R_EXACT_MATCH + 
+	SearchPattern.R_PREFIX_MATCH +
+	SearchPattern.R_PATTERN_MATCH +
+	SearchPattern.R_REGEXP_MATCH +
+	SearchPattern.R_CASE_SENSITIVE;
+
 public static boolean isMatch(char[] pattern, char[] word, int matchRule) {
 	if (pattern == null) return true;
 
 	// need to mask some bits of pattern rule (bug 79790)
-	switch(matchRule & JavaSearchPattern.MATCH_RULE_INDEX_MASK) {
+	switch(matchRule & MATCH_RULE_INDEX_MASK) {
 		case SearchPattern.R_EXACT_MATCH :
 			return CharOperation.equals(pattern, word, false);
 		case SearchPattern.R_PREFIX_MATCH :
@@ -79,9 +55,11 @@
 		case SearchPattern.R_PATTERN_MATCH :
 			return CharOperation.match(pattern, word, false);
 		case SearchPattern.R_EXACT_MATCH + SearchPattern.R_CASE_SENSITIVE :
-			return CharOperation.equals(pattern, word);
+			// avoid message send by comparing first character
+			return pattern[0] == word[0] && CharOperation.equals(pattern, word);
 		case SearchPattern.R_PREFIX_MATCH + SearchPattern.R_CASE_SENSITIVE :
-			return CharOperation.prefixEquals(pattern, word);
+			// avoid message send by comparing first character
+			return pattern[0] == word[0] && CharOperation.prefixEquals(pattern, word);
 		case SearchPattern.R_PATTERN_MATCH + SearchPattern.R_CASE_SENSITIVE :
 			return CharOperation.match(pattern, word, true);
 	}
@@ -89,16 +67,20 @@
 }
 
 
-public Index(String fileName, String printableName, boolean reuseExistingFile) throws IOException {
-	this.printableName = printableName;
+public Index(String fileName, String containerPath, boolean reuseExistingFile) throws IOException {
+	this.containerPath = containerPath;
 	this.monitor = new ReadWriteMonitor();
 
 	this.memoryIndex = new MemoryIndex();
 	this.diskIndex = new DiskIndex(fileName);
 	this.diskIndex.initialize(reuseExistingFile);
 }
-public void addIndexEntry(char[] category, char[] key, InternalSearchDocument document) {
-	this.memoryIndex.addIndexEntry(category, key, document);
+public void addIndexEntry(char[] category, char[] key, String containerRelativePath) {
+	this.memoryIndex.addIndexEntry(category, key, containerRelativePath);
+}
+public String containerRelativePath(String documentPath) {
+	int jarSeparator = documentPath.indexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR);
+	return documentPath.substring((jarSeparator == -1 ? this.containerPath.length() : jarSeparator) + 1);
 }
 public File getIndexFile() {
 	if (this.diskIndex == null) return null;
@@ -123,13 +105,14 @@
 	}
 
 	HashtableOfObject results;
+	int rule = matchRule & MATCH_RULE_INDEX_MASK;
 	if (this.memoryIndex.hasChanged()) {
-		results = this.diskIndex.addQueryResults(categories, key, matchRule, this.memoryIndex);
-		this.memoryIndex.addQueryResults(categories, key, matchRule, results);
+		results = this.diskIndex.addQueryResults(categories, key, rule, this.memoryIndex);
+		results = this.memoryIndex.addQueryResults(categories, key, rule, results);
 	} else {
-		results = this.diskIndex.addQueryResults(categories, key, matchRule, null);
+		results = this.diskIndex.addQueryResults(categories, key, rule, null);
 	}
-	if (results.elementSize == 0) return null;
+	if (results == null) return null;
 
 	EntryResult[] entryResults = new EntryResult[results.elementSize];
 	int count = 0;
@@ -162,8 +145,8 @@
 			documentNames[count++] = (String) paths[i];
 	return documentNames;
 }
-public void remove(String documentName) {
-	this.memoryIndex.remove(documentName);
+public void remove(String containerRelativePath) {
+	this.memoryIndex.remove(containerRelativePath);
 }
 public void save() throws IOException {
 	// must own the write lock of the monitor
@@ -184,7 +167,6 @@
 		this.diskIndex.stopQuery();
 }
 public String toString() {
-	if (this.printableName != null) return this.printableName;
-	return super.toString();
+	return "Index for " + this.containerPath; //$NON-NLS-1$
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java
index 3656e51..c590b02 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/MemoryIndex.java
@@ -1,17 +1,16 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.index;
 
 import org.eclipse.jdt.core.search.*;
-import org.eclipse.jdt.internal.core.search.indexing.InternalSearchDocument;
 import org.eclipse.jdt.internal.core.util.*;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
@@ -41,9 +40,8 @@
 				results.add(paths[i]);
 	}
 }
-void addIndexEntry(char[] category, char[] key, InternalSearchDocument document) {
+void addIndexEntry(char[] category, char[] key, String documentName) {
 	// assumed a document was removed before its reindexed
-	String documentName = document.getPath();
 	HashtableOfObject referenceTable = (HashtableOfObject) this.docsToReferences.get(documentName);
 	if (referenceTable == null)
 		this.docsToReferences.put(documentName, referenceTable = new HashtableOfObject(3));
@@ -54,7 +52,7 @@
 
 	existingWords.add(this.allWords.add(key));
 }
-void addQueryResults(char[][] categories, char[] key, int matchRule, HashtableOfObject results) {
+HashtableOfObject addQueryResults(char[][] categories, char[] key, int matchRule, HashtableOfObject results) {
 	// assumed the disk index already skipped over documents which have been added/changed/deleted
 	// results maps a word -> EntryResult
 	Object[] paths = this.docsToReferences.keyTable;
@@ -66,6 +64,8 @@
 				for (int j = 0, m = categories.length; j < m; j++) {
 					SimpleWordSet wordSet = (SimpleWordSet) categoryToWords.get(categories[j]);
 					if (wordSet != null && wordSet.includes(key)) {
+						if (results == null)
+							results = new HashtableOfObject(13);
 						EntryResult result = (EntryResult) results.get(key);
 						if (result == null)
 							results.put(key, result = new EntryResult(key, null));
@@ -86,6 +86,8 @@
 						for (int k = 0, n = words.length; k < n; k++) {
 							char[] word = words[k];
 							if (word != null && Index.isMatch(key, word, matchRule)) {
+								if (results == null)
+									results = new HashtableOfObject(13);
 								EntryResult result = (EntryResult) results.get(word);
 								if (result == null)
 									results.put(word, result = new EntryResult(word, null));
@@ -97,6 +99,7 @@
 			}
 		}
 	}
+	return results;
 }
 boolean hasChanged() {
 	return this.docsToReferences.elementSize > 0;
@@ -107,4 +110,4 @@
 boolean shouldMerge() {
 	return this.docsToReferences.elementSize >= NUM_CHANGES;
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java
index 20759d2..2e7b21c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/AbstractSearchScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SearchBasicEngine.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
similarity index 67%
rename from org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SearchBasicEngine.java
rename to org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
index fb9d69f..9d39284 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SearchBasicEngine.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/BasicSearchEngine.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,6 +21,7 @@
 import org.eclipse.jdt.internal.compiler.*;
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.env.IGenericType;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.lookup.*;
@@ -30,14 +31,14 @@
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.search.indexing.*;
 import org.eclipse.jdt.internal.core.search.matching.*;
-import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.internal.core.util.Messages;
 
 /**
  * Search basic engine. Public search engine (see {@link org.eclipse.jdt.core.search.SearchEngine}
  * for detailed comment), now uses basic engine functionalities.
  * Note that serch basic engine does not implement deprecated functionalities...
  */
-public class SearchBasicEngine {
+public class BasicSearchEngine {
 
 	/*
 	 * A default parser to parse non-reconciled working copies
@@ -60,26 +61,35 @@
 	/**
 	 * For tracing purpose.
 	 */	
-	public static boolean VERBOSE = false;	
+	public static boolean VERBOSE = false;
 
 	/*
 	 * Creates a new search basic engine.
 	 */
-	public SearchBasicEngine() {
+	public BasicSearchEngine() {
 		// will use working copies of PRIMARY owner
 	}
 	
 	/**
 	 * @see org.eclipse.jdt.core.search.SearchEngine#SearchEngine(ICompilationUnit[]) for detailed comment.
 	 */
-	public SearchBasicEngine(ICompilationUnit[] workingCopies) {
+	public BasicSearchEngine(ICompilationUnit[] workingCopies) {
 		this.workingCopies = workingCopies;
 	}
-	
+
+	char convertTypeKind(int typeDeclarationKind) {
+		switch(typeDeclarationKind) {
+			case IGenericType.CLASS_DECL : return IIndexConstants.CLASS_SUFFIX;
+			case IGenericType.INTERFACE_DECL : return IIndexConstants.INTERFACE_SUFFIX;
+			case IGenericType.ENUM_DECL : return IIndexConstants.ENUM_SUFFIX;
+			case IGenericType.ANNOTATION_TYPE_DECL : return IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+			default : return IIndexConstants.TYPE_SUFFIX;
+		}
+	}
 	/**
 	 * @see org.eclipse.jdt.core.search.SearchEngine#SearchEngine(WorkingCopyOwner) for detailed comment.
 	 */
-	public SearchBasicEngine(WorkingCopyOwner workingCopyOwner) {
+	public BasicSearchEngine(WorkingCopyOwner workingCopyOwner) {
 		this.workingCopyOwner = workingCopyOwner;
 	}
 
@@ -144,7 +154,7 @@
 	 * @return a new workspace scope
 	 */
 	public static IJavaSearchScope createWorkspaceScope() {
-		return new JavaWorkspaceScope();
+		return JavaWorkspaceScope.createScope();
 	}
 	
 	/**
@@ -160,9 +170,11 @@
 	
 		/* initialize progress monitor */
 		if (monitor != null)
-			monitor.beginTask(Util.bind("engine.searching"), 100); //$NON-NLS-1$
-		if (VERBOSE)
-			System.out.println("Searching for " + this + " in " + scope); //$NON-NLS-1$//$NON-NLS-2$
+			monitor.beginTask(Messages.engine_searching, 100); 
+		if (BasicSearchEngine.VERBOSE) {
+			System.out.println("Searching for pattern: " + pattern.toString()); //$NON-NLS-1$
+			System.out.println(scope); //$NON-NLS-1$
+		}
 	
 		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
 		try {
@@ -174,7 +186,7 @@
 				SubProgressMonitor subMonitor= monitor==null ? null : new SubProgressMonitor(monitor, 1000);
 				if (subMonitor != null) subMonitor.beginTask("", 1000); //$NON-NLS-1$
 				try {
-					if (subMonitor != null) subMonitor.subTask(Util.bind("engine.searching.indexing", participant.getDescription())); //$NON-NLS-1$
+					if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_indexing, (new String[] {participant.getDescription()}))); 
 					participant.beginSearching();
 					requestor.enterParticipant(participant);
 					PathCollector pathCollector = new PathCollector();
@@ -185,7 +197,7 @@
 					if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
 	
 					// locate index matches if any (note that all search matches could have been issued during index querying)
-					if (subMonitor != null) subMonitor.subTask(Util.bind("engine.searching.matching", participant.getDescription())); //$NON-NLS-1$
+					if (subMonitor != null) subMonitor.subTask(Messages.bind(Messages.engine_searching_matching, (new String[] {participant.getDescription()}))); 
 					String[] indexMatchPaths = pathCollector.getPaths();
 					pathCollector = null; // release
 					int indexMatchLength = indexMatchPaths == null ? 0 : indexMatchPaths.length;
@@ -474,29 +486,42 @@
 		}
 	
 		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
-			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRestriction access) {
+			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
 				TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
+				AccessRestriction accessRestriction = null;
 				if (record.enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR  // filter out local and anonymous classes
 						&& !workingCopyPaths.contains(documentPath)) { // filter out working copies
 					if (access != null) {
-						access = access.getViolatedRestriction(CharOperation.concat(record.pkg, record.simpleName, '/'), null);					
+						// Compute document relative path
+						int pos = documentPath.lastIndexOf('.');
+						char[] extension = null;
+						if (pos >= 0 && pos > documentPath.lastIndexOf('/')) {
+							extension = documentPath.substring(pos).toCharArray();
+						}
+						int pkgLength = record.pkg==null ? 0 : record.pkg.length+1;
+						int nameLength = record.simpleName==null ? 0 : record.simpleName.length;
+						int extLength = extension==null ? 0 : extension.length;
+						char[] path = new char[pkgLength+nameLength+extLength];
+						pos = 0;
+						if (pkgLength > 0) {
+							System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
+							CharOperation.replace(path, '.', '/');
+							path[pkgLength-1] = '/';
+							pos += pkgLength;
+						}
+						if (nameLength > 0) {
+							System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+							pos += nameLength;
+							if (extLength > 0) {
+								System.arraycopy(extension, 0, path, pos, extLength);
+							}
+						}
+						// Update access restriction if path is not empty
+						if (pos > 0) {
+							accessRestriction = access.getViolatedRestriction(path);
+						}
 					}
-					switch (record.typeSuffix) {
-						case IIndexConstants.CLASS_SUFFIX :
-							nameRequestor.acceptClass(record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, access);
-							break;
-						case IIndexConstants.INTERFACE_SUFFIX :
-							nameRequestor.acceptInterface(record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, access);
-							break;
-						case IIndexConstants.ENUM_SUFFIX :
-							// TODO (frederic) hack to get enum while getting all type names...
-							nameRequestor.acceptEnum(record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, access);
-							break;
-						case IIndexConstants.ANNOTATION_TYPE_SUFFIX :
-							// TODO (frederic) hack to get annotation while getting all type names...
-							nameRequestor.acceptAnnotation(record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, access);
-							break;
-					}
+					nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction);
 				}
 				return true;
 			}
@@ -504,7 +529,7 @@
 	
 		try {
 			if (progressMonitor != null) {
-				progressMonitor.beginTask(Util.bind("engine.searching"), 100); //$NON-NLS-1$
+				progressMonitor.beginTask(Messages.engine_searching, 100); 
 			}
 			// add type names from indexes
 			indexManager.performConcurrentJob(
@@ -537,30 +562,17 @@
 							}
 							char[] simpleName = type.getElementName().toCharArray();
 							int kind;
-							if (type.isClass()) {
-								kind = IGenericType.CLASS_DECL;
-							} else if (type.isInterface()) {
-								kind = IGenericType.INTERFACE_DECL;
-							} else if (type.isEnum()) {
+							if (type.isEnum()) {
 								kind = IGenericType.ENUM_DECL;
-							} else /*if (type.isAnnotation())*/ {
+							} else if (type.isAnnotation()) {
 								kind = IGenericType.ANNOTATION_TYPE_DECL;
+							}	else if (type.isClass()) {
+								kind = IGenericType.CLASS_DECL;
+							} else /*if (type.isInterface())*/ {
+								kind = IGenericType.INTERFACE_DECL;
 							}
 							if (match(typeSuffix, packageName, typeName, matchRule, kind, packageDeclaration, simpleName)) {
-								switch(kind) {
-									case IGenericType.CLASS_DECL:
-										nameRequestor.acceptClass(packageDeclaration, simpleName, enclosingTypeNames, path, null);
-										break;
-									case IGenericType.INTERFACE_DECL:
-										nameRequestor.acceptInterface(packageDeclaration, simpleName, enclosingTypeNames, path, null);
-										break;
-									case IGenericType.ENUM_DECL:
-										// TODO need support
-										break;
-									case IGenericType.ANNOTATION_TYPE_DECL:
-										// TODO need support
-										break;
-								}
+								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
 							}
 						}
 					} else {
@@ -590,20 +602,7 @@
 								}
 								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
 									if (match(typeSuffix, packageName, typeName, matchRule, typeDeclaration.kind(), packageDeclaration, typeDeclaration.name)) {
-										switch(typeDeclaration.kind()) {
-											case IGenericType.CLASS_DECL:
-												nameRequestor.acceptClass(packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
-												break;
-											case IGenericType.INTERFACE_DECL:
-												nameRequestor.acceptInterface(packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
-												break;
-											case IGenericType.ENUM_DECL:
-												// TODO need support
-												break;
-											case IGenericType.ANNOTATION_TYPE_DECL:
-												// TODO need support
-												break;
-										}
+										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
 									}
 									return true;
 								}
@@ -621,21 +620,231 @@
 											}
 										}
 										// report
-										switch(memberTypeDeclaration.kind()) {
-											case IGenericType.CLASS_DECL:
-												nameRequestor.acceptClass(packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
-												break;
-											case IGenericType.INTERFACE_DECL:
-												nameRequestor.acceptInterface(packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
-												break;
-											case IGenericType.ENUM_DECL:
-												// TODO need support
-												break;
-											case IGenericType.ANNOTATION_TYPE_DECL:
-												// TODO need support
-												break;
+										nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
+									}
+									return true;
+								}
+							}
+							parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope);
+						}
+					}
+				}
+			}	
+		} finally {
+			if (progressMonitor != null) {
+				progressMonitor.done();
+			}
+		}
+	}
+
+	/**
+	 * Searches for all top-level types and member types in the given scope using  a case sensitive exact match
+	 * with the given qualified names and type names.
+	 * 
+	 * @param qualifications the qualified name of the package/enclosing type of the searched types
+	 * @param typeNames the simple names of the searched types
+	 * @param scope the scope to search in
+	 * @param nameRequestor the requestor that collects the results of the search
+	 * @param waitingPolicy one of
+	 * <ul>
+	 *		<li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li>
+	 *		<li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the
+	 *			underlying indexer has not finished indexing the workspace</li>
+	 *		<li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the
+	 *			underlying indexer to finish indexing the workspace</li>
+	 * </ul>
+	 * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress
+	 *							monitor is provided
+	 * @exception JavaModelException if the search failed. Reasons include:
+	 *	<ul>
+	 *		<li>the classpath is incorrectly set</li>
+	 *	</ul>
+	 * @since 3.0
+	 */
+	public void searchAllTypeNames(
+		final char[][] qualifications, 
+		final char[][] typeNames,
+		final int matchRule, 
+		int searchFor, 
+		IJavaSearchScope scope, 
+		final IRestrictedAccessTypeRequestor nameRequestor,
+		int waitingPolicy,
+		IProgressMonitor progressMonitor)  throws JavaModelException {
+
+		IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
+
+		final char typeSuffix;
+		switch(searchFor){
+			case IJavaSearchConstants.CLASS :
+				typeSuffix = IIndexConstants.CLASS_SUFFIX;
+				break;
+			case IJavaSearchConstants.INTERFACE :
+				typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
+				break;
+			case IJavaSearchConstants.ENUM :
+				typeSuffix = IIndexConstants.ENUM_SUFFIX;
+				break;
+			case IJavaSearchConstants.ANNOTATION_TYPE :
+				typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+				break;
+			default : 
+				typeSuffix = IIndexConstants.TYPE_SUFFIX;
+				break;
+		}
+		final MultiTypeDeclarationPattern pattern = new MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix, matchRule);
+
+		final HashSet workingCopyPaths = new HashSet();
+		ICompilationUnit[] copies = getWorkingCopies();
+		if (copies != null) {
+			for (int i = 0, length = copies.length; i < length; i++) {
+				ICompilationUnit workingCopy = copies[i];
+				workingCopyPaths.add(workingCopy.getPath().toString());
+			}
+		}
+
+		IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
+			public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
+				if (!workingCopyPaths.contains(documentPath)) { // filter out working copies
+					QualifiedTypeDeclarationPattern record = (QualifiedTypeDeclarationPattern) indexRecord;
+					AccessRestriction accessRestriction = null;
+					if (access != null) {
+						// Compute document relative path
+						int pos = documentPath.lastIndexOf('.');
+						char[] extension = null;
+						if (pos >= 0 && pos > documentPath.lastIndexOf('/'))
+							extension = documentPath.substring(pos).toCharArray();
+						int qualificationLength = record.qualification == null ? 0 : record.qualification.length + 1;
+						int nameLength = record.simpleName == null ? 0 : record.simpleName.length;
+						int extLength = extension == null ? 0 : extension.length;
+						char[] path = new char[qualificationLength + nameLength + extLength];
+						pos = 0;
+						if (qualificationLength > 0) {
+							System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1);
+							CharOperation.replace(path, '.', '/');
+							path[qualificationLength-1] = '/';
+							pos += qualificationLength;
+						}
+						if (nameLength > 0) {
+							System.arraycopy(record.simpleName, 0, path, pos, nameLength);
+							pos += nameLength;
+							if (extLength > 0)
+								System.arraycopy(extension, 0, path, pos, extLength);
+						}
+						// Update access restriction if path is not empty
+						if (pos > 0) {
+							accessRestriction = access.getViolatedRestriction(path);
+						}
+					}
+					nameRequestor.acceptType(record.modifiers, record.getPackageName(), record.simpleName, record.getEnclosingTypeNames(), documentPath, accessRestriction);
+				}
+				return true;
+			}
+		};
+	
+		try {
+			if (progressMonitor != null) {
+				progressMonitor.beginTask(Messages.engine_searching, 100); 
+			}
+			// add type names from indexes
+			indexManager.performConcurrentJob(
+				new PatternSearchJob(
+					pattern, 
+					getDefaultSearchParticipant(), // Java search only
+					scope, 
+					searchRequestor),
+				waitingPolicy,
+				progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));	
+				
+			// add type names from working copies
+			if (copies != null) {
+				for (int i = 0, length = copies.length; i < length; i++) {
+					ICompilationUnit workingCopy = copies[i];
+					final String path = workingCopy.getPath().toString();
+					if (workingCopy.isConsistent()) {
+						IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations();
+						char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray();
+						IType[] allTypes = workingCopy.getAllTypes();
+						for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) {
+							IType type = allTypes[j];
+							IJavaElement parent = type.getParent();
+							char[][] enclosingTypeNames;
+							char[] qualification = packageDeclaration;
+							if (parent instanceof IType) {
+								char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray();
+								enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
+								qualification = CharOperation.concat(qualification, parentQualifiedName);
+							} else {
+								enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+							}
+							char[] simpleName = type.getElementName().toCharArray();
+							char suffix = IIndexConstants.TYPE_SUFFIX;
+							if (type.isClass()) {
+								suffix = IIndexConstants.CLASS_SUFFIX;
+							} else if (type.isInterface()) {
+								suffix = IIndexConstants.INTERFACE_SUFFIX;
+							} else if (type.isEnum()) {
+								suffix = IIndexConstants.ENUM_SUFFIX;
+							} else if (type.isAnnotation()) {
+								suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
+							}
+							if (pattern.matchesDecodedKey(new QualifiedTypeDeclarationPattern(qualification, simpleName, suffix, matchRule))) {
+								nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null);
+							}
+						}
+					} else {
+						Parser basicParser = getParser();
+						final char[] contents = workingCopy.getBuffer().getCharacters();
+						org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() {
+							public char[] getContents() {
+								return contents;
+							}
+							public char[] getMainTypeName() {
+								return null;
+							}
+							public char[][] getPackageName() {
+								return null;
+							}
+							public char[] getFileName() {
+								return null;
+							}
+						};
+						CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit);
+						CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult);
+						if (parsedUnit != null) {
+							final char[] packageDeclaration = parsedUnit.currentPackage == null
+								? CharOperation.NO_CHAR
+								: CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.');
+							class AllTypeDeclarationsVisitor extends ASTVisitor {
+								public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) {
+									return false; // no local/anonymous type
+								}
+								public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) {
+									SearchPattern decodedPattern =
+										new QualifiedTypeDeclarationPattern(packageDeclaration, typeDeclaration.name, convertTypeKind(typeDeclaration.kind()), matchRule);
+									if (pattern.matchesDecodedKey(decodedPattern)) {
+										nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null);
+									}
+									return true;
+								}
+								public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) {
+									// compute encloising type names
+									char[] qualification = packageDeclaration;
+									TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
+									char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
+									while (enclosing != null) {
+										qualification = CharOperation.concat(qualification, enclosing.name, '.');
+										enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames);
+										if ((enclosing.bits & ASTNode.IsMemberTypeMASK) != 0) {
+											enclosing = enclosing.enclosingType;
+										} else {
+											enclosing = null;
 										}
 									}
+									SearchPattern decodedPattern =
+										new QualifiedTypeDeclarationPattern(qualification, memberTypeDeclaration.name, convertTypeKind(memberTypeDeclaration.kind()), matchRule);
+									if (pattern.matchesDecodedKey(decodedPattern)) {
+										nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null);
+									}
 									return true;
 								}
 							}
@@ -658,7 +867,7 @@
 			if (resource instanceof IFile) {
 				try {
 					requestor.beginReporting();
-					if (VERBOSE) {
+					if (BasicSearchEngine.VERBOSE) {
 						System.out.println("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
 					}
 					SearchParticipant participant = getDefaultSearchParticipant();
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java
index a3b0d62..f42d498 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/HierarchyScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java
index ee917f8..dea548a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IRestrictedAccessTypeRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,17 +14,11 @@
 
 /**
  * A <code>IRestrictedAccessTypeRequestor</code> collects search results from a <code>searchAllTypeNames</code>
- * query to a <code>SearchBasicEngine</code> providing restricted access information when a class or an interface is accepted.
- * @see org.eclipse.jdt.core.search.ITypeNameRequestor
+ * query to a <code>SearchBasicEngine</code> providing restricted access information when a type is accepted.
+ * @see org.eclipse.jdt.core.search.TypeNameRequestor
  */
 public interface IRestrictedAccessTypeRequestor {
 	
-	public void acceptAnnotation(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access);
-
-	public void acceptClass(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access);
-
-	public void acceptEnum(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access);
-
-	public void acceptInterface(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access);
+	public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access);
 
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java
index 198450c..e23db53 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexQueryRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,7 @@
 
 import org.eclipse.jdt.core.search.SearchParticipant;
 import org.eclipse.jdt.core.search.SearchPattern;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 
 /**
  * TODO add spec
@@ -20,6 +20,6 @@
 public abstract class IndexQueryRequestor {
 	
 	// answer false if requesting cancel
-	public abstract boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRestriction access);
+	public abstract boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access);
 	
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
index abdc400..887e2aa 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/IndexSelector.java
@@ -1,19 +1,15 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search;
 
-import java.util.ArrayList;
-
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.IClasspathEntry;
@@ -28,6 +24,7 @@
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
 import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
+import org.eclipse.jdt.internal.core.util.SimpleSet;
 
 /**
  * Selects the indexes that correspond to projects in a given search scope
@@ -52,66 +49,66 @@
  */
 public static boolean canSeeFocus(IJavaElement focus, boolean isPolymorphicSearch, IPath projectOrJarPath) {
 	try {
+		IClasspathEntry[] focusEntries = null;
+		if (isPolymorphicSearch) {
+			JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject) focus.getParent() : (JavaProject) focus;
+			focusEntries = focusProject.getExpandedClasspath(true);
+		}
 		IJavaModel model = focus.getJavaModel();
 		IJavaProject project = getJavaProject(projectOrJarPath, model);
-		if (project == null) {
-			// projectOrJarPath is a jar
-			// it can see the focus only if it is on the classpath of a project that can see the focus
-			IJavaProject[] allProjects = model.getJavaProjects();
-			for (int i = 0, length = allProjects.length; i < length; i++) {
-				JavaProject otherProject = (JavaProject) allProjects[i];
-				IClasspathEntry[] entries = otherProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
-				for (int j = 0, length2 = entries.length; j < length2; j++) {
-					IClasspathEntry entry = entries[j];
-					if ((entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) 
-						&& entry.getPath().equals(projectOrJarPath)) {
-							if (canSeeFocus(focus, isPolymorphicSearch, otherProject.getPath())) {
-								return true;
-							}
-					}
-				}
-			}
-			return false;
-		}
-		// projectOrJarPath is a project
-		JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject)focus.getParent() : (JavaProject)focus;
-		if (isPolymorphicSearch) {
-			// look for refering project
-			IClasspathEntry[] entries = focusProject.getExpandedClasspath(true);
-			for (int i = 0, length = entries.length; i < length; i++) {
-				IClasspathEntry entry = entries[i];
-				if ((entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) 
-					&& entry.getPath().equals(projectOrJarPath)) {
+		if (project != null)
+			return canSeeFocus(focus, (JavaProject) project, focusEntries);
+
+		// projectOrJarPath is a jar
+		// it can see the focus only if it is on the classpath of a project that can see the focus
+		IJavaProject[] allProjects = model.getJavaProjects();
+		for (int i = 0, length = allProjects.length; i < length; i++) {
+			JavaProject otherProject = (JavaProject) allProjects[i];
+			IClasspathEntry[] entries = otherProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
+			for (int j = 0, length2 = entries.length; j < length2; j++) {
+				IClasspathEntry entry = entries[j];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(projectOrJarPath))
+					if (canSeeFocus(focus, otherProject, focusEntries))
 						return true;
-				}
+			}
+		}
+		return false;
+	} catch (JavaModelException e) {
+		return false;
+	}
+}
+public static boolean canSeeFocus(IJavaElement focus, JavaProject javaProject, IClasspathEntry[] focusEntriesForPolymorphicSearch) {
+	try {
+		if (focus.equals(javaProject))
+			return true;
+
+		if (focusEntriesForPolymorphicSearch != null) {
+			// look for refering project
+			IPath projectPath = javaProject.getProject().getFullPath();
+			for (int i = 0, length = focusEntriesForPolymorphicSearch.length; i < length; i++) {
+				IClasspathEntry entry = focusEntriesForPolymorphicSearch[i];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(projectPath))
+					return true;
 			}
 		}
 		if (focus instanceof JarPackageFragmentRoot) {
 			// focus is part of a jar
 			IPath focusPath = focus.getPath();
-			IClasspathEntry[] entries = ((JavaProject)project).getExpandedClasspath(true);
+			IClasspathEntry[] entries = javaProject.getExpandedClasspath(true);
 			for (int i = 0, length = entries.length; i < length; i++) {
 				IClasspathEntry entry = entries[i];
-				if ((entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) 
-					&& entry.getPath().equals(focusPath)) {
-						return true;
-				}
-			}
-			return false;
-		} 
-		// focus is part of a project
-		if (focus.equals(project)) {
-			return true;
-		} 
-		// look for dependent projects
-		IPath focusPath = focusProject.getProject().getFullPath();
-		IClasspathEntry[] entries = ((JavaProject)project).getExpandedClasspath(true);
-		for (int i = 0, length = entries.length; i < length; i++) {
-			IClasspathEntry entry = entries[i];
-			if ((entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) 
-				&& entry.getPath().equals(focusPath)) {
+				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(focusPath))
 					return true;
 			}
+			return false;
+		}
+		// look for dependent projects
+		IPath focusPath = ((JavaProject) focus).getProject().getFullPath();
+		IClasspathEntry[] entries = javaProject.getExpandedClasspath(true);
+		for (int i = 0, length = entries.length; i < length; i++) {
+			IClasspathEntry entry = entries[i];
+			if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(focusPath))
+				return true;
 		}
 		return false;
 	} catch (JavaModelException e) {
@@ -122,31 +119,84 @@
  *  Compute the list of paths which are keying index files.
  */
 private void initializeIndexLocations() {
-	
-	ArrayList requiredIndexKeys = new ArrayList();
 	IPath[] projectsAndJars = this.searchScope.enclosingProjectsAndJars();
-	IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-	IJavaElement projectOrJarFocus = MatchLocator.projectOrJarFocus(this.pattern);
-	boolean isPolymorphicSearch = this.pattern == null ? false : MatchLocator.isPolymorphicSearch(this.pattern);
 	IndexManager manager = JavaModelManager.getJavaModelManager().getIndexManager();
-	for (int i = 0; i < projectsAndJars.length; i++) {
-		IPath location;
-		IPath path = projectsAndJars[i];
-		if ((!root.getProject(path.lastSegment()).exists()) // if project does not exist
-			&& path.segmentCount() > 1
-			&& ((location = root.getFile(path).getLocation()) == null
-				|| !new java.io.File(location.toOSString()).exists()) // and internal jar file does not exist
-			&& !new java.io.File(path.toOSString()).exists()) { // and external jar file does not exist
-				continue;
-		}
-		if (projectOrJarFocus == null || canSeeFocus(projectOrJarFocus, isPolymorphicSearch, path)) {
-			if (requiredIndexKeys.indexOf(path) == -1) {
-				requiredIndexKeys.add(new Path(manager.computeIndexLocation(path)));
+	SimpleSet locations = new SimpleSet();
+	IJavaElement focus = MatchLocator.projectOrJarFocus(this.pattern);
+	if (focus == null) {
+		for (int i = 0; i < projectsAndJars.length; i++)
+			locations.add(manager.computeIndexLocation(projectsAndJars[i]));
+	} else {
+		try {
+			// find the projects from projectsAndJars that see the focus then walk those projects looking for the jars from projectsAndJars
+			int length = projectsAndJars.length;
+			JavaProject[] projectsCanSeeFocus = new JavaProject[length];
+			SimpleSet visitedProjects = new SimpleSet(length);
+			int projectIndex = 0;
+			SimpleSet jarsToCheck = new SimpleSet(length);
+			IClasspathEntry[] focusEntries = null;
+			if (this.pattern != null && MatchLocator.isPolymorphicSearch(this.pattern)) { // isPolymorphicSearch
+				JavaProject focusProject = focus instanceof JarPackageFragmentRoot ? (JavaProject) focus.getParent() : (JavaProject) focus;
+				focusEntries = focusProject.getExpandedClasspath(true);
 			}
+			IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel();
+			for (int i = 0; i < length; i++) {
+				IPath path = projectsAndJars[i];
+				JavaProject project = (JavaProject) getJavaProject(path, model);
+				if (project != null) {
+					visitedProjects.add(project);
+					if (canSeeFocus(focus, project, focusEntries)) {
+						locations.add(manager.computeIndexLocation(path));
+						projectsCanSeeFocus[projectIndex++] = project;
+					}
+				} else {
+					jarsToCheck.add(path);
+				}
+			}
+			for (int i = 0; i < projectIndex && jarsToCheck.elementSize > 0; i++) {
+				IClasspathEntry[] entries = projectsCanSeeFocus[i].getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
+				for (int j = entries.length; --j >= 0;) {
+					IClasspathEntry entry = entries[j];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+						IPath path = entry.getPath();
+						if (jarsToCheck.includes(path)) {
+							locations.add(manager.computeIndexLocation(entry.getPath()));
+							jarsToCheck.remove(path);
+						}
+					}
+				}
+			}
+			// jar files can be included in the search scope without including one of the projects that references them, so scan all projects that have not been visited
+			if (jarsToCheck.elementSize > 0) {
+				IJavaProject[] allProjects = model.getJavaProjects();
+				for (int i = 0, l = allProjects.length; i < l && jarsToCheck.elementSize > 0; i++) {
+					JavaProject project = (JavaProject) allProjects[i];
+					if (!visitedProjects.includes(project)) {
+						IClasspathEntry[] entries = project.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
+						for (int j = entries.length; --j >= 0;) {
+							IClasspathEntry entry = entries[j];
+							if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
+								IPath path = entry.getPath();
+								if (jarsToCheck.includes(path)) {
+									locations.add(manager.computeIndexLocation(entry.getPath()));
+									jarsToCheck.remove(path);
+								}
+							}
+						}
+					}
+				}
+			}
+		} catch (JavaModelException e) {
+			// ignored
 		}
 	}
-	this.indexLocations = new IPath[requiredIndexKeys.size()];
-	requiredIndexKeys.toArray(this.indexLocations);
+
+	this.indexLocations = new IPath[locations.elementSize];
+	Object[] values = locations.values;
+	int count = 0;
+	for (int i = values.length; --i >= 0;)
+		if (values[i] != null)
+			this.indexLocations[count++] = new Path((String) values[i]);
 }
 public IPath[] getIndexLocations() {
 	if (this.indexLocations == null) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java
index 1117c79..c4a7704 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchDocument.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -31,10 +31,6 @@
 	public JavaSearchDocument(String documentPath, SearchParticipant participant) {
 		super(documentPath, participant);
 	}
-	public JavaSearchDocument(IFile file, SearchParticipant participant) {
-		super(file.getFullPath().toString(), participant);
-		this.file = file;
-	}
 	public JavaSearchDocument(java.util.zip.ZipEntry zipEntry, IPath zipFilePath, byte[] contents, SearchParticipant participant) {
 		super(zipFilePath + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + zipEntry.getName(), participant);
 		this.byteContents = contents;
@@ -45,7 +41,7 @@
 		try {
 			return org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(getLocation().toFile());
 		} catch (IOException e) {
-			if (SearchBasicEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing
+			if (BasicSearchEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing
 				e.printStackTrace();
 			}
 			return null;
@@ -56,7 +52,7 @@
 		try {
 			return org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(getLocation().toFile(), getEncoding());
 		} catch (IOException e) {
-			if (SearchBasicEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing
+			if (BasicSearchEngine.VERBOSE || JobManager.VERBOSE) { // used during search and during indexing
 				e.printStackTrace();
 			}
 			return null;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java
index 22175c6..6fd0040 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchParticipant.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
index b2ab4c6..b9f378e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -27,7 +27,7 @@
 import org.eclipse.jdt.core.IOpenable;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.JavaElement;
 import org.eclipse.jdt.internal.core.JavaModelManager;
@@ -44,16 +44,22 @@
 	/* The paths of the resources in this search scope 
 	   (or the classpath entries' paths 
 	   if the resources are projects) */
-	private IPath[] paths;
+	private String[] paths;
 	private boolean[] pathWithSubFolders;
-	private AccessRestriction[] pathRestrictions;
+	protected AccessRuleSet[] pathRestrictions;
+	private String[] containerPaths;
 	private int pathsCount;
+	private int threshold;
 	
 	private IPath[] enclosingProjectsAndJars;
-	public final static AccessRestriction UNINIT_RESTRICTION = new AccessRestriction(null, null, null, null);
+	public final static AccessRuleSet NOT_ENCLOSED = new AccessRuleSet(null);
 	
 public JavaSearchScope() {
-	this.initialize();
+	this(5);
+}
+
+private JavaSearchScope(int size) {
+	initialize(size);
 	
 	//disabled for now as this could be expensive
 	//JavaModelManager.getJavaModelManager().rememberScope(this);
@@ -95,7 +101,9 @@
 	IProject project = javaProject.getProject();
 	if (!project.isAccessible() || !visitedProjects.add(project)) return;
 
-	this.addEnclosingProjectOrJar(project.getFullPath());
+	IPath projectPath = project.getFullPath();
+	String projectPathString = projectPath.toString();
+	this.addEnclosingProjectOrJar(projectPath);
 
 	IClasspathEntry[] entries = javaProject.getResolvedClasspath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
 	IJavaModel model = javaProject.getJavaModel();
@@ -107,16 +115,16 @@
 			rawEntry = (IClasspathEntry) perProjectInfo.resolvedPathToRawEntries.get(entry.getPath());
 		}
 		if (rawEntry == null) continue;
-		AccessRestriction access = null;
-		ClasspathEntry cpEntry = null;
-		if (rawEntry instanceof ClasspathEntry) {
-			cpEntry = (ClasspathEntry) rawEntry;
-			if (referringEntry != null) {
-				cpEntry = cpEntry.combineWith(referringEntry);
+		AccessRuleSet access = null;
+		ClasspathEntry cpEntry = (ClasspathEntry) rawEntry;
+		if (referringEntry != null) {
+			// Add only exported entries.
+			// Source folder are implicitly exported.
+			if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) continue;
+			cpEntry = cpEntry.combineWith((ClasspathEntry)referringEntry);
 //				cpEntry = ((ClasspathEntry)referringEntry).combineWith(cpEntry);
-			}
-			access = cpEntry.getImportRestriction();
 		}
+		access = cpEntry.getAccessRuleSet();
 		switch (entry.getEntryKind()) {
 			case IClasspathEntry.CPE_LIBRARY:
 				switch (rawEntry.getEntryKind()) {
@@ -125,7 +133,7 @@
 						if ((includeMask & APPLICATION_LIBRARIES) != 0) {
 							IPath path = entry.getPath();
 							if (pathToAdd == null || pathToAdd.equals(path)) {
-								add(path, true, access);
+								add("", path.toString(), true, access); //$NON-NLS-1$
 								addEnclosingProjectOrJar(path);
 							}
 						}
@@ -137,7 +145,7 @@
 								|| (includeMask & SYSTEM_LIBRARIES) != 0) {
 							IPath path = entry.getPath();
 							if (pathToAdd == null || pathToAdd.equals(path)) {
-								add(path, true, access);
+								add("", path.toString(), true, access); //$NON-NLS-1$
 								addEnclosingProjectOrJar(path);
 							}
 						}
@@ -156,7 +164,7 @@
 				if ((includeMask & SOURCES) != 0) {
 					IPath path = entry.getPath();
 					if (pathToAdd == null || pathToAdd.equals(path)) {
-						add(entry.getPath(), true, access);
+						add(Util.relativePath(path,1/*remove project segment*/), projectPathString, true, access);
 					}
 				}
 				break;
@@ -164,57 +172,38 @@
 	}
 }
 /**
- * Add an element to the java search scope. use element project to retrieve and
- * store access restriction corresponding to the provided element.
+ * Add an element to the java search scope.
  * @param element The element we want to add to current java search scope
  * @throws JavaModelException May happen if some Java Model info are not available
  */
 public void add(IJavaElement element) throws JavaModelException {
-//	add(element, element.getJavaProject());
-	add(element, null);
-}
-/**
- * Add an element to the java search scope. If project is not null, then use it to
- * retrieve and store access restriction corresponding to the provided element.
- * @param element The element we want to add to current java search scope
- * @throws JavaModelException May happen if some Java Model info are not available
- */
-public void add(IJavaElement element, IJavaProject project) throws JavaModelException {
-	IPackageFragmentRoot root = null;
+	IPath containerPath = null;
 	int includeMask = SOURCES | APPLICATION_LIBRARIES | SYSTEM_LIBRARIES;
 	switch (element.getElementType()) {
 		case IJavaElement.JAVA_MODEL:
 			// a workspace sope should be used
 			break; 
 		case IJavaElement.JAVA_PROJECT:
-			if (project == null)
-				add((JavaProject)element, null, includeMask, new HashSet(2), null);
-			else
-				add((JavaProject)project, element.getPath(), includeMask, new HashSet(2), null);
+			add((JavaProject)element, null, includeMask, new HashSet(2), null);
 			break;
 		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
-			root = (IPackageFragmentRoot)element;
-			if (project == null)
-				add(root.getPath(), true, null);
-			else
-				add((JavaProject)project, root.getPath(), includeMask, new HashSet(2), null);
+			IPackageFragmentRoot root = (IPackageFragmentRoot)element;
+			IPath rootPath = root.getPath();
+			containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : rootPath;
+			add("", containerPath.toString(), true, null); //$NON-NLS-1$
 			break;
 		case IJavaElement.PACKAGE_FRAGMENT:
 			root = (IPackageFragmentRoot)element.getParent();
 			if (root.isArchive()) {
 				String relativePath = Util.concatWith(((PackageFragment) element).names, '/');
-				IPath path = root.getPath().append(new Path(relativePath));
-				if (project == null)
-					add(path, false, null);
-				else
-					add((JavaProject)project, path, includeMask, new HashSet(2), null);
+				containerPath = root.getPath();
+				add(relativePath, containerPath.toString(), false, null);
 			} else {
 				IResource resource = element.getResource();
 				if (resource != null && resource.isAccessible()) {
-					if (project == null)
-						add(resource.getFullPath(), false, null);
-					else
-						add((JavaProject)project, resource.getFullPath(), includeMask, new HashSet(2), null);
+					containerPath = root.getKind() == IPackageFragmentRoot.K_SOURCE ? root.getParent().getPath() : root.getPath();
+					String relativePath = Util.relativePath(resource.getFullPath(), containerPath.segmentCount());
+					add(relativePath, containerPath.toString(), false, null);
 				}
 			}
 			break;
@@ -226,100 +215,108 @@
 				}
 				this.elements.add(element);
 			}
-			this.add(this.fullPath(element), true, null);
-			
-			// find package fragment root including this java element
-			IJavaElement parent = element.getParent();
-			while (parent != null && !(parent instanceof IPackageFragmentRoot)) {
-				parent = parent.getParent();
+			root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+			String relativePath;
+			if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
+				containerPath = root.getParent().getPath();
+				relativePath = Util.relativePath(getPath(element, false/*full path*/), 1/*remove project segmet*/);
+			} else {
+				containerPath = root.getPath();
+				relativePath = getPath(element, true/*relative path*/).toString();
 			}
-			if (parent instanceof IPackageFragmentRoot) {
-				root = (IPackageFragmentRoot)parent;
-			}
+			add(relativePath, containerPath.toString(), true, null);
 	}
 	
-	if (root != null) {
-		if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
-			this.addEnclosingProjectOrJar(root.getPath());
-		} else {
-			this.addEnclosingProjectOrJar(root.getJavaProject().getProject().getFullPath());
-		}
-	}
+	if (containerPath != null)
+		addEnclosingProjectOrJar(containerPath);
 }
 
 /**
  * Adds the given path to this search scope. Remember if subfolders need to be included
  * and associated access restriction as well.
  */
-private void add(IPath path, boolean withSubFolders, AccessRestriction access) {
-	if (this.paths.length == this.pathsCount) {
-		System.arraycopy(
-			this.paths,
-			0,
-			this.paths = new IPath[this.pathsCount * 2],
-			0,
-			this.pathsCount);
-		System.arraycopy(
-			this.pathWithSubFolders,
-			0,
-			this.pathWithSubFolders = new boolean[this.pathsCount * 2],
-			0,
-			this.pathsCount);
-		System.arraycopy(
-			this.pathRestrictions,
-			0,
-			this.pathRestrictions = new AccessRestriction[this.pathsCount * 2],
-			0,
-			this.pathsCount);
+private void add(String relativePath, String containerPath, boolean withSubFolders, AccessRuleSet access) {
+	int index = (containerPath.hashCode() & 0x7FFFFFFF) % this.paths.length;
+	String currentPath, currentContainerPath;
+	while ((currentPath = this.paths[index]) != null && (currentContainerPath = this.containerPaths[index]) != null) {
+		if (currentPath.equals(relativePath) && currentContainerPath.equals(containerPath))
+			return;
+		index = (index + 1) % this.paths.length;
 	}
-	this.paths[this.pathsCount] = path;
-	this.pathWithSubFolders[this.pathsCount] = withSubFolders; 
-	this.pathRestrictions[this.pathsCount++] = access;
+	this.paths[index] = relativePath;
+	this.containerPaths[index] = containerPath;
+	this.pathWithSubFolders[index] = withSubFolders;
+	if (this.pathRestrictions != null)
+		this.pathRestrictions[index] = access;
+	else if (access != null) {
+		this.pathRestrictions = new AccessRuleSet[this.paths.length];
+		this.pathRestrictions[index] = access;
+	}
+
+	// assumes the threshold is never equal to the size of the table
+	if (++this.pathsCount > this.threshold)
+		rehash();
+		
 }
 
 /* (non-Javadoc)
  * @see IJavaSearchScope#encloses(String)
  */
 public boolean encloses(String resourcePathString) {
-	return this.encloses(fullPath(resourcePathString)) >= 0;
-}
-private IPath fullPath(String resourcePathString) {
-	IPath resourcePath;
 	int separatorIndex = resourcePathString.indexOf(JAR_FILE_ENTRY_SEPARATOR);
 	if (separatorIndex != -1) {
-		resourcePath = 
-			new Path(resourcePathString.substring(0, separatorIndex)).
-				append(new Path(resourcePathString.substring(separatorIndex+1)));
-	} else {
-			resourcePath = new Path(resourcePathString);
+		return indexOf(resourcePathString.substring(separatorIndex+1), resourcePathString.substring(0, separatorIndex)) >= 0;
 	}
-	return resourcePath;
+	return indexOf(resourcePathString, null) >= 0;
 }
 
 /**
  * Returns paths list index of given path or -1 if not found.
  */
-private int encloses(IPath path) {
-	for (int i = 0; i < this.pathsCount; i++) {
-		if (this.pathWithSubFolders[i]) {
-			if (this.paths[i].isPrefixOf(path)) {
-				return i;
+private int indexOf(String relativePath, String containerPath) {
+	if (containerPath != null) {
+		// if container path is known, use the hash to get faster comparison
+		int index = (containerPath.hashCode()& 0x7FFFFFFF) % this.paths.length;
+		String currentContainerPath;
+		while ((currentContainerPath = this.containerPaths[index]) != null) {
+			if (currentContainerPath.equals(containerPath)) {
+				String scopePath = this.paths[index];
+				if (encloses(scopePath, relativePath, index))
+					return index;
 			}
-		} else {
-			// if not looking at subfolders, this scope encloses the given path 
-			// if this path is a direct child of the scope's ressource
-			// or if this path is the scope's resource (see bug 13919 Declaration for package not found if scope is not project)
-			IPath scopePath = this.paths[i];
-			if (scopePath.isPrefixOf(path) 
-				&& ((scopePath.segmentCount() == path.segmentCount() - 1)
-					|| (scopePath.segmentCount() == path.segmentCount()))) {
-				return i;
-			}
+			index = (index + 1) % this.paths.length;
 		}
+		return -1;
+	}
+	
+	// fallback to sequentially looking at all known paths
+	for (int i = 0, length = this.paths.length; i < length; i++) {
+		String scopePath = this.paths[i];
+		if (scopePath == null) continue;
+		if (encloses(this.containerPaths[i] + '/' + scopePath, relativePath, i))
+			return i;
 	}
 	return -1;
 }
 
+private boolean encloses(String scopePath, String path, int index) {
+	if (this.pathWithSubFolders[index]) {
+		if (path.startsWith(scopePath)) {
+			return true;
+		}
+	} else {
+		// if not looking at subfolders, this scope encloses the given path 
+		// if this path is a direct child of the scope's ressource
+		// or if this path is the scope's resource (see bug 13919 Declaration for package not found if scope is not project)
+		if (path.startsWith(scopePath) 
+			&& ((scopePath.length() == path.lastIndexOf('/'))
+				|| (scopePath.length() == path.length()))) {
+			return true;
+		}
+	}
+	return false;
+}
+
 /* (non-Javadoc)
  * @see IJavaSearchScope#encloses(IJavaElement)
  */
@@ -336,7 +333,13 @@
 		}
 		return false;
 	}
-	return this.encloses(this.fullPath(element)) >= 0;
+	IPackageFragmentRoot root = (IPackageFragmentRoot) element.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+	if (root != null && root.isArchive()) {
+		IPath rootPath = root.getPath();
+		IPath relativePath = getPath(element, true/*relative path*/);
+		return indexOf(relativePath.toString(), rootPath.toString()) >= 0;
+	}
+	return this.indexOf(getPath(element, false/*full path*/).toString(), null) >= 0;
 }
 
 /* (non-Javadoc)
@@ -345,12 +348,14 @@
 public IPath[] enclosingProjectsAndJars() {
 	return this.enclosingProjectsAndJars;
 }
-private IPath fullPath(IJavaElement element) {
+private IPath getPath(IJavaElement element, boolean relativeToRoot) {
 	if (element instanceof IPackageFragmentRoot) {
+		if (relativeToRoot)
+			return Path.EMPTY;
 		return ((IPackageFragmentRoot)element).getPath();
 	}
 	IJavaElement parent = element.getParent();
-	IPath parentPath = parent == null ? null : this.fullPath(parent);
+	IPath parentPath = parent == null ? null : getPath(parent, relativeToRoot);
 	IPath childPath;
 	if (element instanceof PackageFragment) {
 		String relativePath = Util.concatWith(((PackageFragment) element).names, '/');
@@ -364,25 +369,33 @@
 }
 
 /**
- * Get access restriction corresponding to a given path.
- * @param path The path user want to have restriction access
- * @return The access restriction for given path or null if none is set for it.
- * 	Returns specific uninit restriction when scope does not enclose the given path.
+ * Get access rule set corresponding to a given path.
+ * @param relativePath The path user want to have restriction access
+ * @return The access rule set for given path or null if none is set for it.
+ * 	Returns specific uninit access rule set when scope does not enclose the given path.
  */
-public AccessRestriction getAccessRestriction(String path) {
-	int index = encloses(fullPath(path));
+public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath) {
+	int index = indexOf(relativePath, containerPath);
 	if (index == -1) {
 		// this search scope does not enclose given path
-		return UNINIT_RESTRICTION;
+		return NOT_ENCLOSED;
 	}
+	if (this.pathRestrictions == null)
+		return null;
 	return this.pathRestrictions[index];
 }
 
-protected void initialize() {
-	this.paths = new IPath[1];
-	this.pathWithSubFolders = new boolean[1];
-	this.pathRestrictions = new AccessRestriction[1];
+protected void initialize(int size) {
 	this.pathsCount = 0;
+	this.threshold = size; // size represents the expected number of elements
+	int extraRoom = (int) (size * 1.75f);
+	if (this.threshold == extraRoom)
+		extraRoom++;
+	this.paths = new String[extraRoom];
+	this.containerPaths = new String[extraRoom];
+	this.pathWithSubFolders = new boolean[extraRoom];
+	this.pathRestrictions = null; // null to optimize case where no access rules are used
+
 	this.enclosingProjectsAndJars = new IPath[0];
 }
 /*
@@ -419,18 +432,29 @@
 							}
 						}
 						if (toRemove != -1) {
-							int last = this.pathsCount-1;
-							if (toRemove != last) {
-								this.paths[toRemove] = this.paths[last];
-								this.pathWithSubFolders[toRemove] = this.pathWithSubFolders[last];
-							}
-							this.pathsCount--;
+							this.paths[toRemove] = null;
+							rehash();
 						}
 				}
 			}
 			break;
 	}
 }
+
+private void rehash() {
+	JavaSearchScope newScope = new JavaSearchScope(this.pathsCount * 2);		// double the number of expected elements
+	String currentPath;
+	for (int i = this.paths.length; --i >= 0;)
+		if ((currentPath = this.paths[i]) != null)
+			newScope.add(currentPath, this.containerPaths[i], this.pathWithSubFolders[i], this.pathRestrictions == null ? null : this.pathRestrictions[i]);
+
+	this.paths = newScope.paths;
+	this.containerPaths = newScope.containerPaths;
+	this.pathWithSubFolders = newScope.pathWithSubFolders;
+	this.pathRestrictions = newScope.pathRestrictions;
+	this.threshold = newScope.threshold;
+}
+
 public String toString() {
 	StringBuffer result = new StringBuffer("JavaSearchScope on "); //$NON-NLS-1$
 	if (this.elements != null) {
@@ -446,10 +470,15 @@
 			result.append("[empty scope]"); //$NON-NLS-1$
 		} else {
 			result.append("["); //$NON-NLS-1$
-			for (int i = 0; i < this.pathsCount; i++) {
-				IPath path = this.paths[i];
+			for (int i = 0; i < this.paths.length; i++) {
+				String path = this.paths[i];
+				if (path == null) continue;
 				result.append("\n\t"); //$NON-NLS-1$
-				result.append(path.toString());
+				result.append(this.containerPaths[i]);
+				if (path.length() > 0) {
+					result.append('/');
+					result.append(path);
+				}
 			}
 			result.append("\n]"); //$NON-NLS-1$
 		}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
index 3611d6c..0b90852 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,6 +16,7 @@
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaElementDelta;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.core.JavaModelManager;
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.core.IJavaProject;
@@ -26,9 +27,19 @@
  * are included.
  */
 public class JavaWorkspaceScope extends JavaSearchScope {
-	protected boolean needsInitialize;
+
+protected boolean needsInitialize;
+
+private static JavaWorkspaceScope TheWorkspaceScope = null;
 	
-public JavaWorkspaceScope() {
+public static JavaWorkspaceScope createScope() {
+	if (TheWorkspaceScope == null)
+		TheWorkspaceScope = new JavaWorkspaceScope();
+
+	return TheWorkspaceScope;
+}
+
+private JavaWorkspaceScope() {
 	JavaModelManager.getJavaModelManager().rememberScope(this);
 }
 public boolean encloses(IJavaElement element) {
@@ -61,18 +72,23 @@
 }
 public IPath[] enclosingProjectsAndJars() {
 	if (this.needsInitialize) {
-		this.initialize();
+		this.initialize(5);
 	}
 	return super.enclosingProjectsAndJars();
 }
 public boolean equals(Object o) {
   return o instanceof JavaWorkspaceScope;
 }
+public AccessRuleSet getAccessRuleSet(String relativePath, String containerPath) {
+	if (this.pathRestrictions == null) 
+		return null;
+	return super.getAccessRuleSet(relativePath, containerPath);
+}
 public int hashCode() {
 	return JavaWorkspaceScope.class.hashCode();
 }
-public void initialize() {
-	super.initialize();
+public void initialize(int size) {
+	super.initialize(size);
 	try {
 		IJavaProject[] projects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects();
 		for (int i = 0, length = projects.length; i < length; i++) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java
index ea903d4..4d0117b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PathCollector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,7 @@
 
 import org.eclipse.jdt.core.search.SearchParticipant;
 import org.eclipse.jdt.core.search.SearchPattern;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 
 /**
  * Collects the resource paths reported by a client to this search requestor.
@@ -28,7 +28,7 @@
 	/* (non-Javadoc)
 	 * @seeIndexQueryRequestor#acceptIndexMatch(IndexRecord, SearchParticipant, SearchPattern)
 	 */
-	public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRestriction access) {
+	public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
 		paths.add(documentPath);
 		return true;
 	}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java
index 5b7c89d..6e7b749 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/PatternSearchJob.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -86,12 +86,15 @@
 		if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
 		// may trigger some index recreation work
 		String indexLocation = indexLocations[i].toOSString();
-		IPath containerPath = (IPath) indexManager.indexLocations.keyForValue(indexLocation);
-		if (containerPath != null) { // sanity check
-			Index index = indexManager.getIndex(containerPath, indexLocation, true /*reuse index file*/, false /*do not create if none*/);
-			if (index != null)
-				indexes[count++] = index; // only consider indexes which are ready
+		Index index = indexManager.getIndex(indexLocation);
+		if (index == null) {
+			// only need containerPath if the index must be built
+			IPath containerPath = (IPath) indexManager.indexLocations.keyForValue(indexLocation);
+			if (containerPath != null) // sanity check
+				index = indexManager.getIndex(containerPath, indexLocation, true /*reuse index file*/, false /*do not create if none*/);
 		}
+		if (index != null)
+			indexes[count++] = index; // only consider indexes which are ready
 	}
 	if (count == length) 
 		this.areIndexesReady = true;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java
index c42f911..56b12aa 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/SubTypeSearchJob.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java
index e974789..0760716 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/TypeNameRequestorWrapper.java
@@ -1,67 +1,45 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search;
 
-import org.eclipse.jdt.core.search.ITypeNameRequestor;
+import org.eclipse.jdt.core.search.TypeNameRequestor;
 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
 
 /**
- * Wrapper to link previous ITypeNameRequestor and IRestrictedAccessTypeRequestor interfaces.
- * This wrapper is used by {@link org.eclipse.jdt.core.search.SearchEngine#searchAllTypeNames(char[],char[],int,int,org.eclipse.jdt.core.search.IJavaSearchScope,ITypeNameRequestor,int,org.eclipse.core.runtime.IProgressMonitor)}
- * to call {@link SearchBasicEngine#searchAllTypeNames(char[],char[],int,int,org.eclipse.jdt.core.search.IJavaSearchScope,IRestrictedAccessTypeRequestor,int,org.eclipse.core.runtime.IProgressMonitor)}
- * corresponding method.
+ * Wrapper used to link {@link IRestrictedAccessTypeRequestor} with {@link TypeNameRequestor}.
+ * This wrapper specifically allows usage of internal method {@link BasicSearchEngine#searchAllTypeNames(
+ * 	char[] packageName, 
+ * 	char[] typeName,
+ * 	int matchRule, 
+ * 	int searchFor, 
+ * 	org.eclipse.jdt.core.search.IJavaSearchScope scope, 
+ * 	IRestrictedAccessTypeRequestor nameRequestor,
+ * 	int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor) }.
+ * from  API method {@link org.eclipse.jdt.core.search.SearchEngine#searchAllTypeNames(
+ * 	char[] packageName, 
+ * 	char[] typeName,
+ * 	int matchRule, 
+ * 	int searchFor, 
+ * 	org.eclipse.jdt.core.search.IJavaSearchScope scope, 
+ * 	TypeNameRequestor nameRequestor,
+ * 	int waitingPolicy,
+ * 	org.eclipse.core.runtime.IProgressMonitor monitor) }.
  */
 public class TypeNameRequestorWrapper implements IRestrictedAccessTypeRequestor {
-	ITypeNameRequestor requestor;
-	public TypeNameRequestorWrapper(ITypeNameRequestor requestor) {
+	TypeNameRequestor requestor;
+	public TypeNameRequestorWrapper(TypeNameRequestor requestor) {
 		this.requestor = requestor;
 	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.core.search.IAccessedTypeNameRequestor#acceptAnnotation(char[], char[], char[][], java.lang.String, org.eclipse.jdt.internal.compiler.env.AccessRestriction)
-	 */
-	public void acceptAnnotation (	char[] packageName,
-									char[] simpleTypeName,
-									char[][] enclosingTypeNames,
-									String path,
-									AccessRestriction access) {
-		this.requestor.acceptInterface(packageName, simpleTypeName, enclosingTypeNames, path);
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.core.search.IAccessedTypeNameRequestor#acceptClass(char[], char[], char[][], java.lang.String, org.eclipse.jdt.internal.compiler.env.AccessRestriction)
-	 */
-	public void acceptClass (	char[] packageName,
-								char[] simpleTypeName,
-								char[][] enclosingTypeNames,
-								String path,
-								AccessRestriction access) {
-		this.requestor.acceptClass(packageName, simpleTypeName, enclosingTypeNames, path);
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.core.search.IAccessedTypeNameRequestor#acceptEnum(char[], char[], char[][], java.lang.String, org.eclipse.jdt.internal.compiler.env.AccessRestriction)
-	 */
-	public void acceptEnum (	char[] packageName,
-								char[] simpleTypeName,
-								char[][] enclosingTypeNames,
-								String path,
-								AccessRestriction access) {
-		this.requestor.acceptClass(packageName, simpleTypeName, enclosingTypeNames, path);
-	}
-	/* (non-Javadoc)
-	 * @see org.eclipse.jdt.internal.core.search.IAccessedTypeNameRequestor#acceptInterface(char[], char[], char[][], java.lang.String, org.eclipse.jdt.internal.compiler.env.AccessRestriction)
-	 */
-	public void acceptInterface (	char[] packageName,
-									char[] simpleTypeName,
-									char[][] enclosingTypeNames,
-									String path,
-									AccessRestriction access) {
-		this.requestor.acceptInterface(packageName, simpleTypeName, enclosingTypeNames, path);
+	public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
+		this.requestor.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path);
 	}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
index 208bb01..1957109 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AbstractIndexer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,7 +24,7 @@
 		this.document = document;
 	}
 	public void addAnnotationTypeDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames) {
-		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(name, packageName, enclosingTypeNames, ANNOTATION_TYPE_SUFFIX));
+		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(modifiers, name, packageName, enclosingTypeNames));
 		
 		addIndexEntry(
 			SUPER_REF, 
@@ -39,7 +39,7 @@
 			char[] superclass, 
 			char[][] superinterfaces,
 			char[][] typeParameterSignatures) {
-		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(name, packageName, enclosingTypeNames, CLASS_SUFFIX));
+		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(modifiers, name, packageName, enclosingTypeNames));
 
 		if (superclass != null) {
 			superclass = erasure(superclass);
@@ -82,7 +82,7 @@
 		addIndexEntry(CONSTRUCTOR_REF, ConstructorPattern.createIndexKey(simpleTypeName, argCount));
 	}
 	public void addEnumDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, char[][] superinterfaces) {
-		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(name, packageName, enclosingTypeNames, ENUM_SUFFIX));
+		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(modifiers, name, packageName, enclosingTypeNames));
 		
 		addIndexEntry(
 			SUPER_REF, 
@@ -110,7 +110,7 @@
 		this.document.addIndexEntry(category, key);
 	}
 	public void addInterfaceDeclaration(int modifiers, char[] packageName, char[] name, char[][] enclosingTypeNames, char[][] superinterfaces, char[][] typeParameterSignatures) {
-		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(name, packageName, enclosingTypeNames, INTERFACE_SUFFIX));
+		addIndexEntry(TYPE_DECL, TypeDeclarationPattern.createIndexKey(modifiers, name, packageName, enclosingTypeNames));
 
 		if (superinterfaces != null) {
 			for (int i = 0, max = superinterfaces.length; i < max; i++) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
index bc74e7e..832a444 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
index 062691a..387a810 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJarFileToIndex.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -130,10 +130,9 @@
 					for (Enumeration e = zip.entries(); e.hasMoreElements();) {
 						// iterate each entry to index it
 						ZipEntry ze = (ZipEntry) e.nextElement();
-						if (Util.isClassFileName(ze.getName())) {
-							JavaSearchDocument entryDocument = new JavaSearchDocument(ze, zipFilePath, null, null);
-							indexedFileNames.put(entryDocument.getPath(), EXISTS);
-						}
+						String zipEntryName = ze.getName();
+						if (Util.isClassFileName(zipEntryName))
+							indexedFileNames.put(zipEntryName, EXISTS);
 					}
 					boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added
 					if (!needToReindex) {
@@ -149,6 +148,7 @@
 								org.eclipse.jdt.internal.core.util.Util.verbose("-> no indexing required (index is consistent with library) for " //$NON-NLS-1$
 								+ zip.getName() + " (" //$NON-NLS-1$
 								+ (System.currentTimeMillis() - initialTime) + "ms)"); //$NON-NLS-1$
+							this.manager.saveIndex(index); // to ensure its placed into the saved state
 							return true;
 						}
 					}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java
index a751b69..a1090f6 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/BinaryIndexer.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
index c455329..eba9567 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IIndexConstants.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -40,14 +40,15 @@
 	char[] ONE_ZERO = new char[] {'0'}; 
 	char[][] ONE_ZERO_CHAR = new char[][] {ONE_ZERO};
 
-	int PKG_REF_PATTERN = 1;
-	int PKG_DECL_PATTERN = 2;
-	int TYPE_REF_PATTERN = 4;
-	int TYPE_DECL_PATTERN = 8;
-	int SUPER_REF_PATTERN = 16;
-	int CONSTRUCTOR_PATTERN = 32;
-	int FIELD_PATTERN = 64;
-	int METHOD_PATTERN = 128;
-	int OR_PATTERN = 256;
-	int LOCAL_VAR_PATTERN = 512;
+	int PKG_REF_PATTERN = 0x0001;
+	int PKG_DECL_PATTERN = 0x0002;
+	int TYPE_REF_PATTERN = 0x0004;
+	int TYPE_DECL_PATTERN = 0x0008;
+	int SUPER_REF_PATTERN = 0x0010;
+	int CONSTRUCTOR_PATTERN = 0x0020;
+	int FIELD_PATTERN = 0x0040;
+	int METHOD_PATTERN = 0x0080;
+	int OR_PATTERN = 0x0100;
+	int LOCAL_VAR_PATTERN = 0x0200;
+	int TYPE_PARAM_PATTERN = 0x0400;
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
index f38c525..e7b2fea 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -52,13 +52,47 @@
 
 		if (this.isCancelled || progressMonitor != null && progressMonitor.isCanceled()) return true;
 		if (!project.isAccessible()) return true; // nothing to do
-
-		Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
-		if (index == null) return true;
-		ReadWriteMonitor monitor = index.monitor;
-		if (monitor == null) return true; // index got deleted since acquired
-
+		
+		ReadWriteMonitor monitor = null;
 		try {
+			// Get source folder entries. Libraries are done as a separate job
+			JavaProject javaProject = (JavaProject)JavaCore.create(this.project);
+			// Do not create marker nor log problems while getting raw classpath (see bug 41859)
+			IClasspathEntry[] entries = javaProject.getRawClasspath(false, false);
+			int length = entries.length;
+			IClasspathEntry[] sourceEntries = new IClasspathEntry[length];
+			int sourceEntriesNumber = 0;
+			for (int i = 0; i < length; i++) {
+				IClasspathEntry entry = entries[i];
+				if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE)
+					sourceEntries[sourceEntriesNumber++] = entry;
+			}
+			if (sourceEntriesNumber == 0) {
+				IPath projectPath = javaProject.getPath();
+				for (int i = 0; i < length; i++) {
+					IClasspathEntry entry = entries[i];
+					if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(projectPath)) {
+						// the project is also a library folder (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=89815)
+						// ensure a job exists to index it as a binary folder
+						this.manager.indexLibrary(projectPath, this.project);
+						return true;
+					}
+				}
+
+				// nothing to index but want to save an empty index file so its not 'rebuilt' when part of a search request
+				Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+				if (index != null)
+					this.manager.saveIndex(index);
+				return true;
+			}
+			if (sourceEntriesNumber != length)
+				System.arraycopy(sourceEntries, 0, sourceEntries = new IClasspathEntry[sourceEntriesNumber], 0, sourceEntriesNumber);
+	
+			Index index = this.manager.getIndexForUpdate(this.containerPath, true, /*reuse index file*/ true /*create if none*/);
+			if (index == null) return true;
+			monitor = index.monitor;
+			if (monitor == null) return true; // index got deleted since acquired
+			
 			monitor.enterRead(); // ask permission to read
 
 			String[] paths = index.queryDocumentNames(""); // all file names //$NON-NLS-1$
@@ -70,105 +104,100 @@
 				indexedFileNames.put(paths[i], DELETED);
 			final long indexLastModified = max == 0 ? 0L : index.getIndexFile().lastModified();
 
-			JavaProject javaProject = (JavaProject)JavaCore.create(this.project);
-			// Do not create marker nor log problems while getting raw classpath (see bug 41859)
-			IClasspathEntry[] entries = javaProject.getRawClasspath(false, false);
 			IWorkspaceRoot root = this.project.getWorkspace().getRoot();
-			for (int i = 0, length = entries.length; i < length; i++) {
+			for (int i = 0; i < sourceEntriesNumber; i++) {
 				if (this.isCancelled) return false;
 
-				IClasspathEntry entry = entries[i];
-				if ((entry.getEntryKind() == IClasspathEntry.CPE_SOURCE)) { // Index only source folders. Libraries are done as a separate job
-					IResource sourceFolder = root.findMember(entry.getPath());
-					if (sourceFolder != null) {
-						
-						// collect output locations if source is project (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32041)
-						final HashSet outputs = new HashSet();
-						if (sourceFolder.getType() == IResource.PROJECT) {
-							// Do not create marker nor log problems while getting output location (see bug 41859)
-							outputs.add(javaProject.getOutputLocation(false, false));
-							for (int j = 0; j < length; j++) {
-								IPath output = entries[j].getOutputLocation();
-								if (output != null) {
-									outputs.add(output);
-								}
+				IClasspathEntry entry = sourceEntries[i];
+				IResource sourceFolder = root.findMember(entry.getPath());
+				if (sourceFolder != null) {
+					
+					// collect output locations if source is project (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32041)
+					final HashSet outputs = new HashSet();
+					if (sourceFolder.getType() == IResource.PROJECT) {
+						// Do not create marker nor log problems while getting output location (see bug 41859)
+						outputs.add(javaProject.getOutputLocation(false, false));
+						for (int j = 0; j < sourceEntriesNumber; j++) {
+							IPath output = sourceEntries[j].getOutputLocation();
+							if (output != null) {
+								outputs.add(output);
 							}
 						}
-						final boolean hasOutputs = !outputs.isEmpty();
-						
-						final char[][] inclusionPatterns = ((ClasspathEntry) entry).fullInclusionPatternChars();
-						final char[][] exclusionPatterns = ((ClasspathEntry) entry).fullExclusionPatternChars();
-						if (max == 0) {
-							sourceFolder.accept(
-								new IResourceProxyVisitor() {
-									public boolean visit(IResourceProxy proxy) {
-										if (isCancelled) return false;
-										switch(proxy.getType()) {
-											case IResource.FILE :
-												if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
-													IFile file = (IFile) proxy.requestResource();
-													if (file.getLocation() == null) return false;
-													if (exclusionPatterns != null || inclusionPatterns != null)
-														if (Util.isExcluded(file, inclusionPatterns, exclusionPatterns))
-															return false;
-													indexedFileNames.put(file.getFullPath().toString(), file);
-												}
-												return false;
-											case IResource.FOLDER :
-												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;
-										}
-										return true;
-									}
-								},
-								IResource.NONE
-							);
-						} else {
-							sourceFolder.accept(
-								new IResourceProxyVisitor() {
-									public boolean visit(IResourceProxy proxy) {
-										if (isCancelled) return false;
-										switch(proxy.getType()) {
-											case IResource.FILE :
-												if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
-													IFile file = (IFile) proxy.requestResource();
-													IPath location = file.getLocation();
-													if (location == null) return false;
-													if (exclusionPatterns != null || inclusionPatterns != null)
-														if (Util.isExcluded(file, inclusionPatterns, exclusionPatterns))
-															return false;
-													String path = file.getFullPath().toString();
-													indexedFileNames.put(path,
-														indexedFileNames.get(path) == null || indexLastModified < location.toFile().lastModified()
-															? (Object) file
-															: (Object) OK);
-												}
-												return false;
-											case IResource.FOLDER :
+					}
+					final boolean hasOutputs = !outputs.isEmpty();
+					
+					final char[][] inclusionPatterns = ((ClasspathEntry) entry).fullInclusionPatternChars();
+					final char[][] exclusionPatterns = ((ClasspathEntry) entry).fullExclusionPatternChars();
+					if (max == 0) {
+						sourceFolder.accept(
+							new IResourceProxyVisitor() {
+								public boolean visit(IResourceProxy proxy) {
+									if (isCancelled) return false;
+									switch(proxy.getType()) {
+										case IResource.FILE :
+											if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
+												IFile file = (IFile) proxy.requestResource();
+												if (file.getLocation() == null) return false;
 												if (exclusionPatterns != null || inclusionPatterns != null)
-													if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns))
+													if (Util.isExcluded(file, inclusionPatterns, exclusionPatterns))
 														return false;
-												if (hasOutputs && outputs.contains(proxy.requestFullPath()))
-													return false;
-										}
-										return true;
+												indexedFileNames.put(Util.relativePath(file.getFullPath(), 1/*remove project segment*/), file);
+											}
+											return false;
+										case IResource.FOLDER :
+											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;
 									}
-								},
-								IResource.NONE
-							);
-						}
+									return true;
+								}
+							},
+							IResource.NONE
+						);
+					} else {
+						sourceFolder.accept(
+							new IResourceProxyVisitor() {
+								public boolean visit(IResourceProxy proxy) {
+									if (isCancelled) return false;
+									switch(proxy.getType()) {
+										case IResource.FILE :
+											if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(proxy.getName())) {
+												IFile file = (IFile) proxy.requestResource();
+												IPath location = file.getLocation();
+												if (location == null) return false;
+												if (exclusionPatterns != null || inclusionPatterns != null)
+													if (Util.isExcluded(file, inclusionPatterns, exclusionPatterns))
+														return false;
+												String relativePathString = Util.relativePath(file.getFullPath(), 1/*remove project segment*/);
+												indexedFileNames.put(relativePathString,
+													indexedFileNames.get(relativePathString) == null || indexLastModified < location.toFile().lastModified()
+														? (Object) file
+														: (Object) OK);
+											}
+											return false;
+										case IResource.FOLDER :
+											if (exclusionPatterns != null || inclusionPatterns != null)
+												if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns))
+													return false;
+											if (hasOutputs && outputs.contains(proxy.requestFullPath()))
+												return false;
+									}
+									return true;
+								}
+							},
+							IResource.NONE
+						);
 					}
 				}
 			}
 
 			Object[] names = indexedFileNames.keyTable;
 			Object[] values = indexedFileNames.valueTable;
-			for (int i = 0, length = names.length; i < length; i++) {
+			for (int i = 0, namesLength = names.length; i < namesLength; i++) {
 				String name = (String) names[i];
 				if (name != null) {
 					if (this.isCancelled) return false;
@@ -200,7 +229,8 @@
 			this.manager.removeIndex(this.containerPath);
 			return false;
 		} finally {
-			monitor.exitRead(); // free read lock
+			if (monitor != null)
+				monitor.exitRead(); // free read lock
 		}
 		return true;
 	}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java
index 3085cc3..c6d3057 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexBinaryFolder.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,8 +12,8 @@
 
 import java.io.IOException;
 
+import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IResourceProxy;
 import org.eclipse.core.resources.IResourceProxyVisitor;
@@ -26,9 +26,9 @@
 import org.eclipse.jdt.internal.core.util.Util;
 
 public class IndexBinaryFolder extends IndexRequest {
-	IFolder folder;
+	IContainer folder;
 
-	public IndexBinaryFolder(IFolder folder, IndexManager manager) {
+	public IndexBinaryFolder(IContainer folder, IndexManager manager) {
 		super(folder.getFullPath(), manager);
 		this.folder = folder;
 	}
@@ -67,8 +67,10 @@
 						if (proxy.getType() == IResource.FILE) {
 							if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(proxy.getName())) {
 								IFile file = (IFile) proxy.requestResource();
-								if (file.getLocation() != null)
-									indexedFileNames.put(file.getFullPath().toString(), file);
+								if (file.getLocation() != null) {
+									String containerRelativePath = Util.relativePath(file.getFullPath(), containerPath.segmentCount());
+									indexedFileNames.put(containerRelativePath, file);
+								}
 							}
 							return false;
 						}
@@ -89,9 +91,9 @@
 									IFile file = (IFile) proxy.requestResource();
 									IPath location = file.getLocation();
 									if (location != null) {
-										String path = file.getFullPath().toString();
-										indexedFileNames.put(path,
-											indexedFileNames.get(path) == null || indexLastModified < location.toFile().lastModified()
+										String containerRelativePath = Util.relativePath(file.getFullPath(), containerPath.segmentCount());
+										indexedFileNames.put(containerRelativePath,
+											indexedFileNames.get(containerRelativePath) == null || indexLastModified < location.toFile().lastModified()
 												? (Object) file
 												: (Object) OK);
 									}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
index 30b05fa..fb4c740 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -24,10 +24,11 @@
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.index.Index;
-import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope;
+import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
 import org.eclipse.jdt.internal.core.search.PatternSearchJob;
 import org.eclipse.jdt.internal.core.search.processing.IJob;
 import org.eclipse.jdt.internal.core.search.processing.JobManager;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 public class IndexManager extends JobManager implements IIndexConstants {
@@ -96,7 +97,7 @@
  */
 public void cleanUpIndexes() {
 	SimpleLookupTable knownPaths = new SimpleLookupTable();
-	IJavaSearchScope scope = new JavaWorkspaceScope();
+	IJavaSearchScope scope = BasicSearchEngine.createWorkspaceScope();
 	PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null);
 	Index[] selectedIndexes = job.getIndexes(null);
 	for (int j = 0, max = selectedIndexes.length; j < max; j++) {
@@ -162,6 +163,18 @@
  * 
  * Warning: Does not check whether index is consistent (not being used)
  */
+public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
+	String indexLocation = computeIndexLocation(containerPath);
+	return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
+}
+/**
+ * Returns the index for a given project, according to the following algorithm:
+ * - if index is already in memory: answers this one back
+ * - if (reuseExistingFile) then read it and return this index and record it in memory
+ * - if (createIfMissing) then create a new empty index and record it in memory
+ * 
+ * Warning: Does not check whether index is consistent (not being used)
+ */
 public synchronized Index getIndex(IPath containerPath, String indexLocation, boolean reuseExistingFile, boolean createIfMissing) {
 	// Path is already canonical per construction
 	Index index = (Index) indexes.get(indexLocation);
@@ -180,7 +193,7 @@
 			File indexFile = new File(indexLocation);
 			if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
 				try {
-					index = new Index(indexLocation, "Index for " + containerPath.toOSString(), true /*reuse index file*/); //$NON-NLS-1$
+					index = new Index(indexLocation, containerPath.toString(), true /*reuse index file*/); //$NON-NLS-1$
 					indexes.put(indexLocation, index);
 					return index;
 				} catch (IOException e) {
@@ -204,7 +217,7 @@
 			try {
 				if (VERBOSE)
 					Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
-				index = new Index(indexLocation, "Index for " + containerPath.toOSString(), false /*do not reuse index file*/); //$NON-NLS-1$
+				index = new Index(indexLocation, containerPath.toString(), false /*do not reuse index file*/); //$NON-NLS-1$
 				indexes.put(indexLocation, index);
 				return index;
 			} catch (IOException e) {
@@ -218,17 +231,8 @@
 	//System.out.println(" index name: " + path.toOSString() + " <----> " + index.getIndexFile().getName());	
 	return index;
 }
-/**
- * Returns the index for a given project, according to the following algorithm:
- * - if index is already in memory: answers this one back
- * - if (reuseExistingFile) then read it and return this index and record it in memory
- * - if (createIfMissing) then create a new empty index and record it in memory
- * 
- * Warning: Does not check whether index is consistent (not being used)
- */
-public synchronized Index getIndex(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
-	String indexLocation = computeIndexLocation(containerPath);
-	return getIndex(containerPath, indexLocation, reuseExistingFile, createIfMissing);
+public synchronized Index getIndex(String indexLocation) {
+	return (Index) indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed
 }
 public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
 	String indexLocation = computeIndexLocation(containerPath);
@@ -327,15 +331,15 @@
 	Object target = JavaModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true);
 	IndexRequest request = null;
 	if (target instanceof IFile) {
-		request = new AddJarFileToIndex((IFile)target, this);
+		request = new AddJarFileToIndex((IFile) target, this);
 	} else if (target instanceof java.io.File) {
-		if (((java.io.File)target).isFile()) {
+		if (((java.io.File) target).isFile()) {
 			request = new AddJarFileToIndex(path, this);
 		} else {
 			return;
 		}
-	} else if (target instanceof IFolder) {
-		request = new IndexBinaryFolder((IFolder)target, this);
+	} else if (target instanceof IContainer) {
+		request = new IndexBinaryFolder((IContainer) target, this);
 	} else {
 		return;
 	}
@@ -385,7 +389,7 @@
  * Name of the background process
  */
 public String processName(){
-	return Util.bind("process.name"); //$NON-NLS-1$
+	return Messages.process_name; 
 }
 private void rebuildIndex(String indexLocation, IPath containerPath) {
 	IWorkspace workspace = ResourcesPlugin.getWorkspace();
@@ -428,7 +432,7 @@
 
 		if (VERBOSE)
 			Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPath.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
-		index = new Index(indexLocation, "Index for " + containerPath.toOSString(), false /*reuse index file*/); //$NON-NLS-1$
+		index = new Index(indexLocation, containerPath.toString(), false /*reuse index file*/); //$NON-NLS-1$
 		this.indexes.put(indexLocation, index);
 		index.monitor = monitor;
 		return index;
@@ -445,8 +449,8 @@
  * Trigger removal of a resource to an index
  * Note: the actual operation is performed in background
  */
-public void remove(String resourceName, IPath indexedContainer){
-	request(new RemoveFromIndex(resourceName, indexedContainer, this));
+public void remove(String containerRelativePath, IPath indexedContainer){
+	request(new RemoveFromIndex(containerRelativePath, indexedContainer, this));
 }
 /**
  * Removes the index for a given path. 
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
index ae74453..a5bf8a2 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexRequest.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/InternalSearchDocument.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/InternalSearchDocument.java
index acf2d4a..d3cf048 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/InternalSearchDocument.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/InternalSearchDocument.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,19 +17,25 @@
  */
 public class InternalSearchDocument {
 	Index index;
+	private String containerRelativePath;
 	/*
 	 * Hidden by API SearchDocument subclass
 	 */
 	public void addIndexEntry(char[] category, char[] key) {
 		if (this.index != null)
-			index.addIndexEntry(category, key, this);
+			index.addIndexEntry(category, key, getContainerRelativePath());
+	}
+	private String getContainerRelativePath() {
+		if (this.containerRelativePath == null)
+			this.containerRelativePath = this.index.containerRelativePath(getPath());
+		return this.containerRelativePath;
 	}
 	/*
 	 * Hidden by API SearchDocument subclass
 	 */
 	public void removeAllIndexEntries() {
 		if (this.index != null)
-			index.remove(getPath());
+			index.remove(getContainerRelativePath());
 	}
 	/*
 	 * Hidden by API SearchDocument subclass
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java
index bf44009..c106de9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ReadWriteMonitor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java
index e569201..b64645a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -45,16 +45,18 @@
 
 		try {
 			monitor.enterRead(); // ask permission to read
-			String[] paths = index.queryDocumentNames(this.folderPath.toString());
+			String containerRelativePath = Util.relativePath(this.folderPath, this.containerPath.segmentCount());
+			String[] paths = index.queryDocumentNames(containerRelativePath);
 			// all file names belonging to the folder or its subfolders and that are not excluded (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32607)
 			if (this.exclusionPatterns == null && this.inclusionPatterns == null) {
-				for (int i = 0, max = paths == null ? 0 : paths.length; i < max; i++)
+				for (int i = 0, max = paths == null ? 0 : paths.length; i < max; i++) {
 					manager.remove(paths[i], this.containerPath); // write lock will be acquired by the remove operation
+				}
 			} else {
 				for (int i = 0, max = paths == null ? 0 : paths.length; i < max; i++) {
-					String documentPath = paths[i];
+					String documentPath =  this.containerPath.toString() + '/' + paths[i];
 					if (!Util.isExcluded(new Path(documentPath), this.inclusionPatterns, this.exclusionPatterns, false))
-						manager.remove(documentPath, this.containerPath); // write lock will be acquired by the remove operation
+						manager.remove(paths[i], this.containerPath); // write lock will be acquired by the remove operation
 				}
 			}
 		} catch (IOException e) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java
index 4f2552d..b4e5e68 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/RemoveFromIndex.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java
index 403ffe1..d1316df 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SaveIndex.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
index 03ef30b..684ff50 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexer.java
@@ -1,16 +1,17 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search.indexing;
 
 import java.util.Locale;
+import java.util.Map;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -51,11 +52,15 @@
 		String documentPath = this.document.getPath();
 		IPath path = new Path(documentPath);
 		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(path.segment(0));
+		Map options = JavaCore.create(project).getOptions(true);
+		// disable task tags to speed up parsing
+		options.put(JavaCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
 		SourceElementParser parser = new SourceElementParser(
 			requestor, 
 			this.problemFactory, 
-			new CompilerOptions(JavaCore.create(project).getOptions(true)), 
-			true); // index local declarations
+			new CompilerOptions(options), 
+			true/*index local declarations*/,
+			true/*optimize string literals*/);
 		parser.reportOnlyOneSyntaxError = true;
 	
 		// Always check javadoc while indexing
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
index 58f5911..f386716 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java
index b4e102b..fee376a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/AndPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -67,10 +67,11 @@
 	}
 	if (intersectedNames == null) return;
 
+	String containerPath = index.containerPath;
 	Object[] names = intersectedNames.values;
 	for (int i = 0, l = names.length; i < l; i++)
 		if (names[i] != null)
-			((InternalSearchPattern) this).acceptMatch((String) names[i], null, requestor, participant, scope); // AndPatterns cannot provide the decoded result
+			((InternalSearchPattern) this).acceptMatch((String) names[i], containerPath, null/*no pattern*/, requestor, participant, scope); // AndPatterns cannot provide the decoded result
 }
 /**
  * Returns whether another query must be done.
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
index 84390bb..ea70f40 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClassFileMatchLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -55,8 +55,10 @@
 	// check class definition
 	SearchPattern pattern = locator.pattern;
 	BinaryType binaryType = (BinaryType) classFile.getType();
-	if (matchBinary(pattern, info, null))
-		locator.reportBinaryMemberDeclaration(null, binaryType, info, SearchMatch.A_ACCURATE);
+	if (matchBinary(pattern, info, null)) {
+		binaryType = new ResolvedBinaryType((JavaElement) binaryType.getParent(), binaryType.getElementName(), binaryType.getKey());
+		locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE);
+	}
 
 	int accuracy = SearchMatch.A_ACCURATE;
 	if (((InternalSearchPattern)pattern).mustResolve) {
@@ -73,7 +75,7 @@
 						IMethod methodHandle = binaryType.getMethod(
 							new String(method.isConstructor() ? binding.compoundName[binding.compoundName.length-1] : method.selector),
 							CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.signature()))));
-						locator.reportBinaryMemberDeclaration(null, methodHandle, info, SearchMatch.A_ACCURATE);
+						locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, SearchMatch.A_ACCURATE);
 					}
 				}
 
@@ -82,7 +84,7 @@
 					FieldBinding field = fields[i];
 					if (locator.patternLocator.resolveLevel(field) == PatternLocator.ACCURATE_MATCH) {
 						IField fieldHandle = binaryType.getField(new String(field.name));
-						locator.reportBinaryMemberDeclaration(null, fieldHandle, info, SearchMatch.A_ACCURATE);
+						locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, SearchMatch.A_ACCURATE);
 					}
 				}
 
@@ -110,10 +112,11 @@
 				} else {
 					name = method.getSelector();
 				}
-				IMethod methodHandle = binaryType.getMethod(
-					new String(name),
-					CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor()))));
-				locator.reportBinaryMemberDeclaration(null, methodHandle, info, accuracy);
+				String selector = new String(name);
+				String[] parameterTypes = CharOperation.toStrings(Signature.getParameterTypes(convertClassFileFormat(method.getMethodDescriptor())));
+				IMethod methodHandle = binaryType.getMethod(selector, parameterTypes);
+				methodHandle = new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey());
+				locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy);
 			}
 		}
 	}
@@ -123,8 +126,10 @@
 		for (int i = 0, l = fields.length; i < l; i++) {
 			IBinaryField field = fields[i];
 			if (matchBinary(pattern, field, info)) {
-				IField fieldHandle = binaryType.getField(new String(field.getName()));
-				locator.reportBinaryMemberDeclaration(null, fieldHandle, info, accuracy);
+				String fieldName = new String(field.getName());
+				IField fieldHandle = binaryType.getField(fieldName);
+				fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey());
+				locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy);
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
index cf5e38b..040cceb 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ClasspathSourceDirectory.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -101,8 +101,9 @@
 public NameEnvironmentAnswer findClass(String sourceFileWithoutExtension, String qualifiedPackageName, String qualifiedSourceFileWithoutExtension) {
 	
 	String sourceFolderPath = this.sourceFolder.getFullPath().toString() + IPath.SEPARATOR;
-	for (int i = 0, length = Util.JAVA_LIKE_EXTENSIONS.length; i < length; i++) {
-		String extension = new String(Util.JAVA_LIKE_EXTENSIONS[i]);
+	char[][] javaLikeExtensions = Util.getJavaLikeExtensions();
+	for (int i = 0, length = javaLikeExtensions.length; i < length; i++) {
+		String extension = new String(javaLikeExtensions[i]);
 		String sourceFileName = sourceFileWithoutExtension + extension;
 		if (!doesFileExist(sourceFileName, qualifiedPackageName)) continue; // most common case
 	
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
index 67efa1b..731521d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorLocator.java
@@ -1,20 +1,27 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search.matching;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.SearchPattern;
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 
 public class ConstructorLocator extends PatternLocator {
 
@@ -29,7 +36,7 @@
 	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
 	if (!(node instanceof ExplicitConstructorCall)) return IMPOSSIBLE_MATCH;
 
-	if (this.pattern.parameterSimpleNames != null) {
+	if (this.pattern.parameterSimpleNames != null && (this.pattern.shouldCountParameter() || ((node.bits & ASTNode.InsideJavadoc) != 0))) {
 		int length = this.pattern.parameterSimpleNames.length;
 		Expression[] args = ((ExplicitConstructorCall) node).arguments;
 		int argsLength = args == null ? 0 : args.length;
@@ -54,7 +61,7 @@
 	if (this.pattern.declaringSimpleName != null && !matchesName(this.pattern.declaringSimpleName, typeName[typeName.length-1]))
 		return IMPOSSIBLE_MATCH;
 
-	if (this.pattern.parameterSimpleNames != null) {
+	if (this.pattern.parameterSimpleNames != null && (this.pattern.shouldCountParameter() || ((node.bits & ASTNode.InsideJavadoc) != 0))) {
 		int length = this.pattern.parameterSimpleNames.length;
 		Expression[] args = allocation.arguments;
 		int argsLength = args == null ? 0 : args.length;
@@ -74,7 +81,7 @@
 			return IMPOSSIBLE_MATCH;
 	}
 
-	if (this.pattern.parameterSimpleNames != null) {
+	if (this.pattern.parameterSimpleNames != null && this.pattern.shouldCountParameter()) {
 		int length = this.pattern.parameterSimpleNames.length;
 		Expression[] args = allocation.arguments;
 		int argsLength = args == null ? 0 : args.length;
@@ -84,7 +91,17 @@
 	return nodeSet.addMatch(field, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
 }
 //public int match(MethodDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
-//public int match(MessageSend node, MatchingNodeSet nodeSet) - SKIP IT
+/**
+ * Special case for message send in javadoc comment. They can be in fact bound to a contructor.
+ * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=83285"
+ */
+public int match(MessageSend msgSend, MatchingNodeSet nodeSet)  {
+	if ((msgSend.bits & ASTNode.InsideJavadoc) == 0) return IMPOSSIBLE_MATCH;
+	if (this.pattern.declaringSimpleName == null || CharOperation.equals(msgSend.selector, this.pattern.declaringSimpleName)) {
+		return nodeSet.addMatch(msgSend, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
+	}
+	return IMPOSSIBLE_MATCH;
+}
 //public int match(Reference node, MatchingNodeSet nodeSet) - SKIP IT
 public int match(TypeDeclaration node, MatchingNodeSet nodeSet) {
 	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
@@ -94,6 +111,35 @@
 }
 //public int match(TypeReference node, MatchingNodeSet nodeSet) - SKIP IT
 
+protected int matchConstructor(MethodBinding constructor) {
+	if (!constructor.isConstructor()) return IMPOSSIBLE_MATCH;
+
+	// declaring type, simple name has already been matched by matchIndexEntry()
+	int level = resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, constructor.declaringClass);
+	if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+
+	// parameter types
+	int parameterCount = this.pattern.parameterSimpleNames == null ? -1 : this.pattern.parameterSimpleNames.length;
+	if (parameterCount > -1) {
+		if (constructor.parameters == null) return INACCURATE_MATCH;
+		if (parameterCount != constructor.parameters.length) return IMPOSSIBLE_MATCH;
+		for (int i = 0; i < parameterCount; i++) {
+			// TODO (frederic) use this call to refine accuracy on parameter types
+//			int newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, constructor.parameters[i]);
+			int newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], constructor.parameters[i]);
+			if (level > newLevel) {
+				if (newLevel == IMPOSSIBLE_MATCH) {
+//					if (isErasureMatch) {
+//						return ERASURE_MATCH;
+//					}
+					return IMPOSSIBLE_MATCH;
+				}
+				level = newLevel; // can only be downgraded
+			}
+		}
+	}
+	return level;
+}
 protected int matchContainer() {
 	if (this.pattern.findReferences) return ALL_CONTAINER; // handles both declarations + references & just references
 	// COMPILATION_UNIT_CONTAINER - implicit constructor call: case of Y extends X and Y doesn't define any constructor
@@ -127,16 +173,94 @@
 		Argument[] args = constructor.arguments;
 		int argsLength = args == null ? 0 : args.length;
 		if (length != argsLength) return IMPOSSIBLE_MATCH;
+	}
 
-		for (int i = 0; i < length; i++)
-			if (!matchesTypeReference(this.pattern.parameterSimpleNames[i], args[i].type))
-				return IMPOSSIBLE_MATCH;
+	// Verify type arguments (do not reject if pattern has no argument as it can be an erasure match)
+	if (this.pattern.hasConstructorArguments()) {
+		if (constructor.typeParameters == null || constructor.typeParameters.length != this.pattern.constructorArguments.length) return IMPOSSIBLE_MATCH;
 	}
 
 	return ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
 }
-public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, int accuracy, int length, MatchLocator locator) {
-	SearchMatch match = null;
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+
+	MethodBinding constructorBinding = null;
+	boolean isSynthetic = false;
+	if (reference instanceof ExplicitConstructorCall) {
+		ExplicitConstructorCall call = (ExplicitConstructorCall) reference;
+		isSynthetic = call.isImplicitSuper();
+		constructorBinding = call.binding;
+	} else if (reference instanceof AllocationExpression) {
+		AllocationExpression alloc = (AllocationExpression) reference;
+		constructorBinding = alloc.binding;
+	} else if (reference instanceof TypeDeclaration || reference instanceof FieldDeclaration) {
+		super.matchReportReference(reference, element, elementBinding, accuracy, locator);
+		if (match != null) return;
+	}
+
+	// Create search match
+	match = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, true, isSynthetic, reference);
+
+	// Look to refine accuracy
+	if (constructorBinding instanceof ParameterizedGenericMethodBinding) { // parameterized generic method
+		// Update match regarding constructor type arguments
+		ParameterizedGenericMethodBinding parameterizedMethodBinding = (ParameterizedGenericMethodBinding) constructorBinding;
+		match.setRaw(parameterizedMethodBinding.isRaw);
+		TypeBinding[] typeBindings = parameterizedMethodBinding.isRaw ? null : parameterizedMethodBinding.typeArguments;
+		updateMatch(typeBindings, locator, this.pattern.constructorArguments, this.pattern.hasConstructorParameters());
+
+		// Update match regarding declaring class type arguments
+		if (constructorBinding.declaringClass.isParameterizedType() || constructorBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)constructorBinding.declaringClass;
+			if (!this.pattern.hasTypeArguments() && this.pattern.hasConstructorArguments()) {
+				// special case for constructor pattern which defines arguments but no type
+				// in this case, we only use refined accuracy for constructor
+			} else if (this.pattern.hasTypeArguments() && !this.pattern.hasConstructorArguments()) {
+				// special case for constructor pattern which defines no constructor arguments but has type ones
+				// in this case, we do not use refined accuracy
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			} else {
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding constructor parameters
+		// TODO ? (frederic)
+	} else if (constructorBinding instanceof ParameterizedMethodBinding) {
+		// Update match regarding declaring class type arguments
+		if (constructorBinding.declaringClass.isParameterizedType() || constructorBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)constructorBinding.declaringClass;
+			if (!this.pattern.hasTypeArguments() && this.pattern.hasConstructorArguments()) {
+				// special case for constructor pattern which defines arguments but no type
+				updateMatch(parameterizedBinding, new char[][][] {this.pattern.constructorArguments}, this.pattern.hasTypeParameters(), 0, locator);
+			} else {
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding constructor parameters
+		// TODO ? (frederic)
+	} else if (this.pattern.hasConstructorArguments()) { // binding has no type params, compatible erasure if pattern does
+		match.setRule(SearchPattern.R_ERASURE_MATCH);
+	}
+
+	// See whether it is necessary to report or not
+	if (match.getRule() == 0) return; // impossible match
+	boolean report = (this.isErasureMatch && match.isErasure()) || (this.isEquivalentMatch && match.isEquivalent()) || match.isExact();
+	if (!report) return;
+
+	// Report match
+	int offset = reference.sourceStart;
+	match.setOffset(offset);
+	match.setLength(reference.sourceEnd - offset + 1);
+	locator.report(match);
+}
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding binding, int accuracy, int length, MatchLocator locator) {
+	match = null;
 	int offset = reference.sourceStart;
 	if (this.pattern.findReferences) {
 		if (reference instanceof TypeDeclaration) {
@@ -146,21 +270,21 @@
 				for (int i = 0, max = methods.length; i < max; i++) {
 					AbstractMethodDeclaration method = methods[i];
 					boolean synthetic = method.isDefaultConstructor() && method.sourceStart < type.bodyStart;
-					match = locator.newMethodReferenceMatch(element, accuracy, offset, length, method.isConstructor(), synthetic, method);
+					match = locator.newMethodReferenceMatch(element, binding, accuracy, offset, length, method.isConstructor(), synthetic, method);
 				}
 			}
 		} else if (reference instanceof ConstructorDeclaration) {
 			ConstructorDeclaration constructor = (ConstructorDeclaration) reference;
 			ExplicitConstructorCall call = constructor.constructorCall;
 			boolean synthetic = call != null && call.isImplicitSuper();
-			match = locator.newMethodReferenceMatch(element, accuracy, offset, length, constructor.isConstructor(), synthetic, constructor);
+			match = locator.newMethodReferenceMatch(element, binding, accuracy, offset, length, constructor.isConstructor(), synthetic, constructor);
 		}
 	}
 	if (match != null) {
 		return match;
 	}
 	// super implementation...
-    return locator.newDeclarationMatch(element, accuracy, reference.sourceStart, length);
+    return locator.newDeclarationMatch(element, binding, accuracy, reference.sourceStart, length);
 }
 public int resolveLevel(ASTNode node) {
 	if (this.pattern.findReferences) {
@@ -172,6 +296,9 @@
 			return resolveLevel((TypeDeclaration) node);
 		if (node instanceof FieldDeclaration)
 			return resolveLevel((FieldDeclaration) node);
+		if (node instanceof JavadocMessageSend) {
+			return resolveLevel(((JavadocMessageSend)node).binding);
+		}
 	}
 	if (node instanceof ConstructorDeclaration)
 		return resolveLevel((ConstructorDeclaration) node, true);
@@ -201,24 +328,11 @@
 	if (binding == null) return INACCURATE_MATCH;
 	if (!(binding instanceof MethodBinding)) return IMPOSSIBLE_MATCH;
 
-	MethodBinding method = ((MethodBinding) binding).original();
-	if (!method.isConstructor()) return IMPOSSIBLE_MATCH;
-
-	// declaring type, simple name has already been matched by matchIndexEntry()
-	int level = resolveLevelForType(this.pattern.declaringSimpleName, this.pattern.declaringQualification, method.declaringClass);
-	if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
-
-	// parameter types
-	int parameterCount = this.pattern.parameterSimpleNames == null ? -1 : this.pattern.parameterSimpleNames.length;
-	if (parameterCount > -1) {
-		if (method.parameters == null) return INACCURATE_MATCH;
-		if (parameterCount != method.parameters.length) return IMPOSSIBLE_MATCH;
-		for (int i = 0; i < parameterCount; i++) {
-			int newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], method.parameters[i]);
-			if (level > newLevel) {
-				if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
-				level = newLevel; // can only be downgraded
-			}
+	MethodBinding constructor = (MethodBinding) binding;
+	int level= matchConstructor(constructor);
+	if (level== IMPOSSIBLE_MATCH) {
+		if (constructor != constructor.original()) {
+			level= matchConstructor(constructor.original());
 		}
 	}
 	return level;
@@ -253,4 +367,4 @@
 public String toString() {
 	return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
index 5d8f5c8..1e6c055 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/ConstructorPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,10 +12,16 @@
 
 import java.io.IOException;
 
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.SearchPattern;
-import org.eclipse.jdt.internal.core.index.*;
+import org.eclipse.jdt.internal.core.index.EntryResult;
+import org.eclipse.jdt.internal.core.index.Index;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
 
 public class ConstructorPattern extends JavaSearchPattern implements IIndexConstants {
 
@@ -28,7 +34,13 @@
 public char[][] parameterQualifications;
 public char[][] parameterSimpleNames;
 public int parameterCount;
-public boolean varargs;
+public int flags = 0;
+
+// Signatures and arguments for generic search
+char[][][] parametersTypeSignatures;
+char[][][][] parametersTypeArguments;
+boolean constructorParameters = false;
+char[][] constructorArguments;
 
 protected static char[][] REF_CATEGORIES = { CONSTRUCTOR_REF };
 protected static char[][] REF_AND_DECL_CATEGORIES = { CONSTRUCTOR_REF, CONSTRUCTOR_DECL };
@@ -45,6 +57,9 @@
 	return CharOperation.concat(typeName, countChars);
 }
 
+ConstructorPattern(int matchRule) {
+	super(CONSTRUCTOR_PATTERN, matchRule);
+}
 public ConstructorPattern(
 	boolean findDeclarations,
 	boolean findReferences,
@@ -52,7 +67,6 @@
 	char[] declaringQualification,
 	char[][] parameterQualifications,
 	char[][] parameterSimpleNames,
-	boolean varargs,
 	int matchRule) {
 
 	this(matchRule);
@@ -73,11 +87,122 @@
 	} else {
 		this.parameterCount = -1;
 	}
-	this.varargs = varargs;
 	((InternalSearchPattern)this).mustResolve = mustResolve();
 }
-ConstructorPattern(int matchRule) {
-	super(CONSTRUCTOR_PATTERN, matchRule);
+/*
+ * Instanciate a method pattern with signatures for generics search
+ */
+public ConstructorPattern(
+	boolean findDeclarations,
+	boolean findReferences,
+	char[] declaringSimpleName,	
+	char[] declaringQualification,
+	char[][] parameterQualifications, 
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	IMethod method,
+//	boolean varargs,
+	int matchRule) {
+
+	this(findDeclarations,
+		findReferences,
+		declaringSimpleName,	
+		declaringQualification,
+		parameterQualifications, 
+		parameterSimpleNames,
+		matchRule);
+
+	// Set flags
+	try {
+		this.flags = method.getFlags();
+	} catch (JavaModelException e) {
+		// do nothing
+	}
+
+	// Get unique key for parameterized constructors
+	String genericDeclaringTypeSignature = null;
+	BindingKey key;
+	if (method.isResolved() && (key = new BindingKey(method.getKey())).isParameterizedType()) {
+		genericDeclaringTypeSignature = key.getDeclaringTypeSignature();
+	} else {
+		constructorParameters = true;
+	}
+
+	// Store type signature and arguments for declaring type
+	if (genericDeclaringTypeSignature != null) {
+		this.typeSignatures = Util.splitTypeLevelsSignature(genericDeclaringTypeSignature);
+		setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+	} else {
+		storeTypeSignaturesAndArguments(method.getDeclaringType());
+	}
+
+	// store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			parametersTypeSignatures = new char[length][][];
+			parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				parametersTypeArguments[i] = Util.getAllTypeArguments(parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	constructorArguments = extractMethodArguments(method);
+	if (hasConstructorArguments())  ((InternalSearchPattern)this).mustResolve = true;
+}
+/*
+ * Instanciate a method pattern with signatures for generics search
+ */
+public ConstructorPattern(
+	boolean findDeclarations,
+	boolean findReferences,
+	char[] declaringSimpleName,	
+	char[] declaringQualification,
+	String declaringSignature,
+	char[][] parameterQualifications, 
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	char[][] arguments,
+	int matchRule) {
+
+	this(findDeclarations,
+		findReferences,
+		declaringSimpleName,	
+		declaringQualification,
+		parameterQualifications, 
+		parameterSimpleNames,
+		matchRule);
+
+	// Store type signature and arguments for declaring type
+	if (declaringSignature != null) {
+		typeSignatures = Util.splitTypeLevelsSignature(declaringSignature);
+		setTypeArguments(Util.getAllTypeArguments(typeSignatures));
+	}
+
+	// Store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			parametersTypeSignatures = new char[length][][];
+			parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				parametersTypeArguments[i] = Util.getAllTypeArguments(parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	constructorArguments = arguments;
+	if (arguments  == null || arguments.length == 0) {
+		if (getTypeArguments() != null && getTypeArguments().length > 0) {
+			constructorArguments = getTypeArguments()[0];
+		}
+	}
+	if (hasConstructorArguments())  ((InternalSearchPattern)this).mustResolve = true;
 }
 public void decodeIndexKey(char[] key) {
 	int size = key.length;
@@ -96,10 +221,16 @@
 		return DECL_CATEGORIES;
 	return CharOperation.NO_CHAR_CHAR;
 }
+boolean hasConstructorArguments() {
+	return constructorArguments != null && constructorArguments.length > 0;
+}
+boolean hasConstructorParameters() {
+	return constructorParameters;
+}
 public boolean matchesDecodedKey(SearchPattern decodedPattern) {
 	ConstructorPattern pattern = (ConstructorPattern) decodedPattern;
 
-	return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+	return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || !shouldCountParameter())
 		&& matchesName(this.declaringSimpleName, pattern.declaringSimpleName);
 }
 protected boolean mustResolve() {
@@ -117,7 +248,7 @@
 
 	switch(getMatchMode()) {
 		case R_EXACT_MATCH :
-			if (!this.varargs && this.declaringSimpleName != null && this.parameterCount >= 0)
+			if (shouldCountParameter() && this.declaringSimpleName != null && this.parameterCount >= 0)
 				key = createIndexKey(this.declaringSimpleName, this.parameterCount);
 			else // do a prefix query with the declaringSimpleName
 				matchRule = matchRule - R_EXACT_MATCH + R_PREFIX_MATCH;
@@ -126,7 +257,7 @@
 			// do a prefix query with the declaringSimpleName
 			break;
 		case R_PATTERN_MATCH :
-			if (!this.varargs && this.parameterCount >= 0)
+			if (shouldCountParameter() && this.parameterCount >= 0)
 				key = createIndexKey(this.declaringSimpleName == null ? ONE_STAR : this.declaringSimpleName, this.parameterCount);
 			else if (this.declaringSimpleName != null && this.declaringSimpleName[this.declaringSimpleName.length - 1] != '*')
 				key = CharOperation.concat(this.declaringSimpleName, ONE_STAR, SEPARATOR);
@@ -164,4 +295,7 @@
 	output.append(')');
 	return super.print(output);
 }
-}
\ No newline at end of file
+boolean shouldCountParameter() {
+	return (this.flags & Flags.AccStatic) == 0 && (this.flags & Flags.AccVarargs) == 0;
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java
index 287758a..0445086 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfAccessedFieldsPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java
index 5049416..fe58552 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedMethodsPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -21,7 +21,7 @@
 protected SimpleSet knownMethods;
 
 public DeclarationOfReferencedMethodsPattern(IJavaElement enclosingElement) {
-	super(false, true, null, null, null, null, null, null, null, false, null, R_PATTERN_MATCH);
+	super(false, true, null, null, null, null, null, null, null, null, R_PATTERN_MATCH);
 
 	this.enclosingElement = enclosingElement;
 	this.knownMethods = new SimpleSet();
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java
index cb98f4e..f908e3f 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/DeclarationOfReferencedTypesPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
index 8896971..6c5e12d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,6 +19,7 @@
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.core.JavaElement;
 import org.eclipse.jdt.internal.core.util.SimpleSet;
 
 public class FieldLocator extends VariableLocator {
@@ -133,7 +134,7 @@
 	}
 	return super.matchReference(node, nodeSet, writeOnlyAccess);
 }
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	if (this.isDeclarationOfAccessedFieldsPattern) {
 		// need exact match to be able to open on type ref
 		if (accuracy != SearchMatch.A_ACCURATE) return;
@@ -147,9 +148,9 @@
 				reportDeclaration(((FieldReference) reference).binding, locator, declPattern.knownFields);
 			} else if (reference instanceof QualifiedNameReference) {
 				QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
-				Binding binding = qNameRef.binding;
-				if (binding instanceof FieldBinding)
-					reportDeclaration((FieldBinding)binding, locator, declPattern.knownFields);
+				Binding nameBinding = qNameRef.binding;
+				if (nameBinding instanceof FieldBinding)
+					reportDeclaration((FieldBinding)nameBinding, locator, declPattern.knownFields);
 				int otherMax = qNameRef.otherBindings == null ? 0 : qNameRef.otherBindings.length;
 				for (int i = 0; i < otherMax; i++)
 					reportDeclaration(qNameRef.otherBindings[i], locator, declPattern.knownFields);
@@ -163,91 +164,87 @@
 		int lastIndex = importRef.tokens.length - 1;
 		int start = (int) ((positions[lastIndex]) >>> 32);
 		int end = (int) positions[lastIndex];
-		SearchMatch match = locator.newFieldReferenceMatch(element, accuracy, start, end-start+1, importRef);
+		match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, start, end-start+1, importRef);
 		locator.report(match);
 	} else if (reference instanceof FieldReference) {
 		FieldReference fieldReference = (FieldReference) reference;
 		long position = fieldReference.nameSourcePosition;
 		int start = (int) (position >>> 32);
 		int end = (int) position;
-		SearchMatch match = locator.newFieldReferenceMatch(element, accuracy, start, end-start+1, fieldReference);
+		match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, start, end-start+1, fieldReference);
 		locator.report(match);
 	} else if (reference instanceof SingleNameReference) {
 		int offset = reference.sourceStart;
-		SearchMatch match = locator.newFieldReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
+		match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference);
 		locator.report(match);
 	} else if (reference instanceof QualifiedNameReference) {
 		QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
 		int length = qNameRef.tokens.length;
-		int[] accuracies = new int[length];
-		Binding binding = qNameRef.binding;
+		SearchMatch[] matches = new SearchMatch[length];
+		Binding nameBinding = qNameRef.binding;
 		int indexOfFirstFieldBinding = qNameRef.indexOfFirstFieldBinding > 0 ? qNameRef.indexOfFirstFieldBinding-1 : 0;
-		for (int i = 0; i < indexOfFirstFieldBinding; i++)
-			accuracies[i] = -1;
+
 		// first token
-		if (matchesName(this.pattern.name, qNameRef.tokens[indexOfFirstFieldBinding]) && !(binding instanceof LocalVariableBinding)) {
-			FieldBinding fieldBinding = binding instanceof FieldBinding ? (FieldBinding) binding : null;
+		if (matchesName(this.pattern.name, qNameRef.tokens[indexOfFirstFieldBinding]) && !(nameBinding instanceof LocalVariableBinding)) {
+			FieldBinding fieldBinding = nameBinding instanceof FieldBinding ? (FieldBinding) nameBinding : null;
 			if (fieldBinding == null) {
-				accuracies[indexOfFirstFieldBinding] = accuracy;
+				matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, elementBinding, accuracy, -1, -1, reference);
 			} else {
 				switch (matchField(fieldBinding, false)) {
 					case ACCURATE_MATCH:
-						accuracies[indexOfFirstFieldBinding] = SearchMatch.A_ACCURATE;
+						matches[indexOfFirstFieldBinding] = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference);
 						break;
 					case INACCURATE_MATCH:
-						if (fieldBinding.type.isParameterizedType() && this.pattern.isParameterized())
-							accuracies[indexOfFirstFieldBinding] = refineAccuracy(SearchMatch.A_INACCURATE, (ParameterizedTypeBinding) fieldBinding.type, this.pattern.typeArguments, locator);
-						else
-							accuracies[indexOfFirstFieldBinding] = SearchMatch.A_INACCURATE;
+						match = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference);
+						if (fieldBinding.type.isParameterizedType() && this.pattern.hasTypeArguments()) {
+							updateMatch((ParameterizedTypeBinding) fieldBinding.type, this.pattern.getTypeArguments(), locator);
+						}
+						matches[indexOfFirstFieldBinding] = match;
 						break;
-					default:
-						accuracies[indexOfFirstFieldBinding] = -1;
 				}
 			}
-		} else {
-			accuracies[indexOfFirstFieldBinding] = -1;
 		}
+
 		// other tokens
 		for (int i = indexOfFirstFieldBinding+1; i < length; i++) {
 			char[] token = qNameRef.tokens[i];
 			if (matchesName(this.pattern.name, token)) {
 				FieldBinding otherBinding = qNameRef.otherBindings == null ? null : qNameRef.otherBindings[i-(indexOfFirstFieldBinding+1)];
 				if (otherBinding == null) {
-					accuracies[i] = accuracy;
+					matches[i] = locator.newFieldReferenceMatch(element, elementBinding, accuracy, -1, -1, reference);
 				} else {
 					switch (matchField(otherBinding, false)) {
 						case ACCURATE_MATCH:
-							accuracies[i] = SearchMatch.A_ACCURATE;
+							matches[i] = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_ACCURATE, -1, -1, reference);
 							break;
 						case INACCURATE_MATCH:
-							if (otherBinding.type.isParameterizedType() && this.pattern.isParameterized())
-								accuracies[i] = refineAccuracy(SearchMatch.A_INACCURATE, (ParameterizedTypeBinding) otherBinding.type, this.pattern.typeArguments, locator);
-							else
-								accuracies[i] = SearchMatch.A_INACCURATE;
-								break;
-						default:
-							accuracies[i] = -1;
+							match = locator.newFieldReferenceMatch(element, elementBinding, SearchMatch.A_INACCURATE, -1, -1, reference);
+							if (otherBinding.type.isParameterizedType() && this.pattern.hasTypeArguments()) {
+								updateMatch((ParameterizedTypeBinding) otherBinding.type, this.pattern.getTypeArguments(), locator);
+							}
+							matches[indexOfFirstFieldBinding] = match;
+							break;
 					}
 				}
-			} else {
-				accuracies[i] = -1;
 			}
 		}
-		locator.reportAccurateFieldReference(qNameRef, element, accuracies);
+		locator.reportAccurateFieldReference(matches, qNameRef);
 	}
 }
-	/* (non-Javadoc)
-	 * Overridden to filter rule values from refined accuracy.
-	 * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#refineAccuracy(int, org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding, char[][][], org.eclipse.jdt.internal.core.search.matching.MatchLocator)
-	 */
-	protected int refineAccuracy(int accuracy, ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) {
-		// We can only refine if locator has an unit scope.
-		if (locator.unitScope == null) return accuracy;
-		int refinedAccuracy = refineAccuracy(accuracy, parameterizedBinding, patternTypeArguments, false, 0, locator);
-		if (refinedAccuracy > SearchMatch.A_INACCURATE)
-			return -1; // canot accept neither erasure nor compatible match
-		return refinedAccuracy;
+/* (non-Javadoc)
+ * Overridden to reject unexact matches.
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#updateMatch(org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding, char[][][], org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ *
+ */
+protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) {
+	// We can only refine if locator has an unit scope.
+	if (locator.unitScope == null) return;
+	updateMatch(parameterizedBinding, patternTypeArguments, false, 0, locator);
+	if (!match.isExact()) {
+		// cannot accept neither erasure nor compatible match
+		match.setRule(0);
 	}
+}
 protected void reportDeclaration(FieldBinding fieldBinding, MatchLocator locator, SimpleSet knownFields) throws CoreException {
 	// ignore length field
 	if (fieldBinding == ArrayBinding.ArrayLength) return;
@@ -268,7 +265,7 @@
 		if (resource == null)
 			resource = type.getJavaProject().getProject();
 		info = locator.getBinaryInfo((org.eclipse.jdt.internal.core.ClassFile) type.getClassFile(), resource);
-		locator.reportBinaryMemberDeclaration(resource, field, info, SearchMatch.A_ACCURATE);
+		locator.reportBinaryMemberDeclaration(resource, field, fieldBinding, info, SearchMatch.A_ACCURATE);
 	} else {
 		if (declaringClass instanceof ParameterizedTypeBinding)
 			declaringClass = ((ParameterizedTypeBinding) declaringClass).type;
@@ -285,7 +282,7 @@
 			} 
 			if (fieldDecl != null) {
 				int offset = fieldDecl.sourceStart;
-				SearchMatch match = new FieldDeclarationMatch(field, SearchMatch.A_ACCURATE, offset, fieldDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
+				match = new FieldDeclarationMatch(((JavaElement) field).resolved(fieldBinding), SearchMatch.A_ACCURATE, offset, fieldDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
 				locator.report(match);
 			}
 		}
@@ -348,7 +345,7 @@
 	return resolveLevelForType(
 			fieldPattern.typeSimpleName,
 			fieldPattern.typeQualification,
-			fieldPattern.typeArguments,
+			fieldPattern.getTypeArguments(),
 			0,
 			typeBinding);
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java
index 3504cfb..8368bcb 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/FieldPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -13,6 +13,7 @@
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.SearchPattern;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
 
 public class FieldPattern extends VariablePattern implements IIndexConstants {
 
@@ -64,12 +65,16 @@
 	char[] declaringSimpleName,	
 	char[] typeQualification, 
 	char[] typeSimpleName,
-	String signature,
+	String typeSignature,
 	int matchRule) {
 
 	this(findDeclarations, readAccess, writeAccess, name, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName, matchRule);
 
-	if (signature != null) computeSignature(signature);
+	// store type signatures and arguments
+	if (typeSignature != null) {
+		this.typeSignatures = Util.splitTypeLevelsSignature(typeSignature);
+		setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+	}
 }
 public void decodeIndexKey(char[] key) {
 	this.name = key;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/InternalSearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/InternalSearchPattern.java
index b24ab4a..a7097d9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/InternalSearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/InternalSearchPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,7 +15,8 @@
 import org.eclipse.core.runtime.*;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.search.*;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.Util;
 import org.eclipse.jdt.internal.core.index.*;
 import org.eclipse.jdt.internal.core.search.*;
 
@@ -32,26 +33,37 @@
 	int kind;
 	boolean mustResolve = true;
 	
-	void acceptMatch(String documentName, SearchPattern pattern, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope) {
-		String documentPath = Index.convertPath(documentName);
+	void acceptMatch(String relativePath, String containerPath, SearchPattern pattern, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope) {
 
 		if (scope instanceof JavaSearchScope) {
 			JavaSearchScope javaSearchScope = (JavaSearchScope) scope;
 			// Get document path access restriction from java search scope
 			// Note that requestor has to verify if needed whether the document violates the access restriction or not
-			AccessRestriction access = javaSearchScope.getAccessRestriction(documentPath);
-			if (JavaSearchScope.UNINIT_RESTRICTION != access) { // scope encloses the document path
+			AccessRuleSet access = javaSearchScope.getAccessRuleSet(relativePath, containerPath);
+			if (access != JavaSearchScope.NOT_ENCLOSED) { // scope encloses the document path
+				String documentPath = documentPath(containerPath, relativePath);
 				if (!requestor.acceptIndexMatch(documentPath, pattern, participant, access)) 
 					throw new OperationCanceledException();
 			}
-		} else if (scope.encloses(documentPath)) {
-			if (!requestor.acceptIndexMatch(documentPath, pattern, participant, null)) 
-				throw new OperationCanceledException();
+		} else {
+			String documentPath = documentPath(containerPath, relativePath);
+			if (scope.encloses(documentPath)) 
+				if (!requestor.acceptIndexMatch(documentPath, pattern, participant, null)) 
+					throw new OperationCanceledException();
+			
 		}
 	}
 	SearchPattern currentPattern() {
 		return (SearchPattern) this;
 	}
+	String documentPath(String containerPath, String relativePath) {
+		String separator = Util.isArchiveFileName(containerPath) ? IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR : "/"; //$NON-NLS-1$
+		StringBuffer buffer = new StringBuffer(containerPath.length() + separator.length() + relativePath.length());
+		buffer.append(containerPath);
+		buffer.append(separator);
+		buffer.append(relativePath);
+		return buffer.toString();
+	}
 	/**
 	 * Query a given index for matching entries. Assumes the sender has opened the index and will close when finished.
 	 */
@@ -64,15 +76,17 @@
 			if (entries == null) return;
 		
 			SearchPattern decodedResult = pattern.getBlankPattern();
+			String containerPath = index.containerPath;
 			for (int i = 0, l = entries.length; i < l; i++) {
 				if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();
 		
 				EntryResult entry = entries[i];
 				decodedResult.decodeIndexKey(entry.getWord());
 				if (pattern.matchesDecodedKey(decodedResult)) {
+					// TODO (kent) some clients may not need the document names
 					String[] names = entry.getDocumentNames(index);
 					for (int j = 0, n = names.length; j < n; j++)
-						acceptMatch(names[j], decodedResult, requestor, participant, scope);
+						acceptMatch(names[j], containerPath, decodedResult, requestor, participant, scope);
 				}
 			}
 		} finally {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
index 9015229..b7786a5 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -59,7 +59,7 @@
 			IPackageDeclaration[] pkgs = workingCopy.getPackageDeclarations();
 			String pkg = pkgs.length > 0 ? pkgs[0].getElementName() : ""; //$NON-NLS-1$
 			String cuName = workingCopy.getElementName();
-			String mainTypeName = cuName.substring(0, Util.indexOfJavaLikeExtension(cuName));
+			String mainTypeName = Util.getNameWithoutJavaLikeExtension(cuName);
 			String qualifiedMainTypeName = pkg.length() == 0 ? mainTypeName : pkg.replace('.', '/') + '/' + mainTypeName;
 			this.workingCopies.put(qualifiedMainTypeName, workingCopy);
 		}
@@ -94,7 +94,7 @@
 		try {
 			if (root.isArchive()) {
 				ZipFile zipFile = manager.getZipFile(path);
-				cpLocations[index++] = new ClasspathJar(zipFile, ((ClasspathEntry) root.getRawClasspathEntry()).getImportRestriction());
+				cpLocations[index++] = new ClasspathJar(zipFile, ((ClasspathEntry) root.getRawClasspathEntry()).getAccessRuleSet());
 			} else {
 				Object target = JavaModel.getTarget(workspaceRoot, path, false);
 				if (target == null) {
@@ -104,7 +104,7 @@
 				} else if (root.getKind() == IPackageFragmentRoot.K_SOURCE) {
 					cpLocations[index++] = new ClasspathSourceDirectory((IContainer)target, root.fullExclusionPatternChars(), root.fullInclusionPatternChars());
 				} else {
-					cpLocations[index++] = ClasspathLocation.forBinaryFolder((IContainer) target, false, ((ClasspathEntry) root.getRawClasspathEntry()).getImportRestriction());
+					cpLocations[index++] = ClasspathLocation.forBinaryFolder((IContainer) target, false, ((ClasspathEntry) root.getRawClasspathEntry()).getAccessRuleSet());
 				}
 			}
 		} catch (CoreException e1) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
index 31bb7a1..b5edcd7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchPattern.java
@@ -1,18 +1,25 @@
 /*******************************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search.matching;
 
+import org.eclipse.jdt.core.BindingKey;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.util.Util;
 
 
 public class JavaSearchPattern extends SearchPattern {
@@ -21,38 +28,47 @@
 	 * Whether this pattern is case sensitive.
 	 */
 	boolean isCaseSensitive;
-	
+
 	/*
 	 * Whether this pattern is erasure match.
 	 */
-	boolean isErasureMatch;
+//	boolean isErasureMatch;
 
-	/*
-	 * One of R_EXACT_MATCH, R_PREFIX_MATCH, R_PATTERN_MATCH, R_REGEXP_MATCH.
+	/**
+	 * One of {@link #R_EXACT_MATCH}, {@link #R_PREFIX_MATCH}, {@link #R_PATTERN_MATCH}, {@link #R_REGEXP_MATCH}.
 	 */
 	int matchMode;
 
 	/**
+	 * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
+	 */
+	int matchCompatibility;
+
+	/**
 	 * Mask used on match rule for match mode.
 	 */
 	public static final int MATCH_MODE_MASK = R_EXACT_MATCH + R_PREFIX_MATCH + R_PATTERN_MATCH + R_REGEXP_MATCH;
 
 	/**
-	 * Mask used on match rule for indexing.
+	 * Mask used on match rule for generic relevance.
 	 */
-	public static final int MATCH_RULE_INDEX_MASK = MATCH_MODE_MASK + R_CASE_SENSITIVE;
+	public static final int MATCH_COMPATIBILITY_MASK = R_ERASURE_MATCH + R_EQUIVALENT_MATCH + R_FULL_MATCH;
 
-	
 	// Signatures and arguments for parameterized types search
 	char[][] typeSignatures;
-	char[][][] typeArguments;
+	private char[][][] typeArguments;
+	private int flags = 0;
+	static final int HAS_TYPE_ARGUMENTS = 1;
 
 	protected JavaSearchPattern(int patternKind, int matchRule) {
 		super(matchRule);
 		((InternalSearchPattern)this).kind = patternKind;
-		this.isCaseSensitive = (matchRule & R_CASE_SENSITIVE) != 0;
-		this.isErasureMatch = (matchRule & SearchPattern.R_ERASURE_MATCH) != 0;
-		this.matchMode = matchRule & MATCH_MODE_MASK;
+		// Use getMatchRule() instead of matchRule as super constructor may modify its value
+		// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=81377
+		int rule = getMatchRule();
+		this.isCaseSensitive = (rule & R_CASE_SENSITIVE) != 0;
+		this.matchCompatibility = rule & MATCH_COMPATIBILITY_MASK;
+		this.matchMode = rule & MATCH_MODE_MASK;
 	}
 	
 	public SearchPattern getBlankPattern() {
@@ -68,96 +84,87 @@
 	}
 
 	boolean isErasureMatch() {
-		return this.isErasureMatch;
+		return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
+	}
+
+	boolean isEquivalentMatch() {
+		return (this.matchCompatibility & R_EQUIVALENT_MATCH) != 0;
+	}
+
+	/*
+	 * Extract method arguments using unique key for parameterized methods
+	 * and type parameters for non-generic ones.
+	 */
+	char[][] extractMethodArguments(IMethod method) {
+		String[] argumentsSignatures = null;
+		BindingKey key;
+		if (method.isResolved() && (key = new BindingKey(method.getKey())).isParameterizedType()) {
+			argumentsSignatures = key.getTypeArguments();
+		} else {
+			try {
+				ITypeParameter[] parameters = method.getTypeParameters();
+				int length = parameters==null ? 0 : parameters.length;
+				if (length > 0) {
+					char[][] arguments = new char[length][];
+					for (int i=0; i<length; i++) {
+						arguments[i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
+					}
+					return arguments;
+				}
+			}
+			catch (JavaModelException jme) {
+				// do nothing
+			}
+			return null;
+		}
+
+		// Parameterized method
+		int length = argumentsSignatures==null ? 0 : argumentsSignatures.length;
+		if (length > 0) {
+			char[][] methodArguments = new char[length][];
+			for (int i=0; i<length; i++) {
+				methodArguments[i] = argumentsSignatures[i].toCharArray();
+				CharOperation.replace(methodArguments[i], new char[] { '$', '/' }, '.');
+			}
+			return methodArguments;
+		}
+		return null;
 	}
 
 	/**
-	 * Returns whether the pattern includess type arguments information or not.
-	 * @return true if pattern has signature *and* type arguments
+	 * @return Returns the typeArguments.
 	 */
-	public boolean isParameterized() {
-		return this.typeArguments != null && this.typeArguments.length > 0;
+	final char[][][] getTypeArguments() {
+		return typeArguments;
 	}
 
-	/* (non-Javadoc)
-	 * Compute a IJavaElement signature or a string pattern signature to store
-	 * its type arguments. Recurse when signature is qualified to store signatures and
-	 * type arguments also for of all enclosing types.
+	/**
+	 * Returns whether the pattern has signatures or not.
+	 * If pattern {@link #typeArguments} field, this field shows that it was built
+	 * on a generic source type.
+	 * @return true if {@link #typeSignatures} field is not null and has a length greater than 0.
 	 */
-	void computeSignature(String signature) {
-		// In case of IJavaElement signature, replace '/' by '.'
-		char[] source = signature.replace('/','.').replace('$','.').toCharArray();
-
-		// Init counters and arrays
-		char[][] signatures = new char[10][];
-		int signaturesCount = 0;
-		int[] lengthes = new int [10];
-		int typeArgsCount = 0;
-		int paramOpening = 0;
-		boolean parameterized = false;
-		
-		// Scan each signature character
-		for (int idx=0, ln = source.length; idx < ln; idx++) {
-			switch (source[idx]) {
-				case '>':
-					paramOpening--;
-					if (paramOpening == 0)  {
-						if (signaturesCount == lengthes.length) {
-							System.arraycopy(signatures, 0, signatures = new char[signaturesCount+10][], 0, signaturesCount);
-							System.arraycopy(lengthes, 0, lengthes = new int[signaturesCount+10], 0, signaturesCount);
-						}
-						lengthes[signaturesCount] = typeArgsCount;
-						typeArgsCount = 0;
-					}
-					break;
-				case '<':
-					paramOpening++;
-					if (paramOpening == 1) {
-						typeArgsCount = 0;
-						parameterized = true;
-					}
-					break;
-				case '*':
-				case ';':
-					if (paramOpening == 1) typeArgsCount++;
-					break;
-				case '.':
-					if (paramOpening == 0)  {
-						if (signaturesCount == lengthes.length) {
-							System.arraycopy(signatures, 0, signatures = new char[signaturesCount+10][], 0, signaturesCount);
-							System.arraycopy(lengthes, 0, lengthes = new int[signaturesCount+10], 0, signaturesCount);
-						}
-						signatures[signaturesCount] = new char[idx+1];
-						System.arraycopy(source, 0, signatures[signaturesCount], 0, idx);
-						signatures[signaturesCount][idx] = Signature.C_SEMICOLON;
-						signaturesCount++;
-					}
-					break;
-			}
-		}
-		
-		// Store signatures and type arguments
-		this.typeSignatures = new char[signaturesCount+1][];
-		if (parameterized)
-			this.typeArguments = new char[signaturesCount+1][][];
-		this.typeSignatures[0] = source;
-		if (parameterized) {
-			this.typeArguments[0] = Signature.getTypeArguments(source);
-			if (lengthes[signaturesCount] != this.typeArguments[0].length) {
-				// TODO (frederic) abnormal signature => should raise an error
-			}
-		}
-		for (int i=1, j=signaturesCount-1; i<=signaturesCount; i++, j--){
-			this.typeSignatures[i] = signatures[j];
-			if (parameterized) {
-				this.typeArguments[i] = Signature.getTypeArguments(signatures[j]);
-				if (lengthes[j] != this.typeArguments[i].length) {
-					// TODO (frederic) abnormal signature => should raise an error
-				}
-			}
-		}
+	public final boolean hasSignatures() {
+		return this.typeSignatures != null && this.typeSignatures.length > 0;
 	}
 
+	/**
+	 * Returns whether the pattern includes type arguments information or not.
+	 * @return default is false
+	 */
+	public final boolean hasTypeArguments() {
+		return (this.flags & HAS_TYPE_ARGUMENTS) != 0;
+	}
+
+	/**
+	 * Returns whether the pattern includes type parameters information or not.
+	 * @return true if {@link #typeArguments} contains type parameters instead
+	 * 	type arguments signatures.
+	 */
+	public final boolean hasTypeParameters() {
+		return !hasSignatures() && hasTypeArguments();
+	}
+	
 	/*
 	 * Optimization of implementation above (uses cached matchMode and isCaseSenistive)
 	 */
@@ -171,6 +178,7 @@
 					return CharOperation.prefixEquals(pattern, name, this.isCaseSensitive);
 				case R_PATTERN_MATCH :
 					if (!this.isCaseSensitive)
+						 // TODO do we really need to this? should we add a 'fast' method when we know its already been done?
 						pattern = CharOperation.toLowerCase(pattern);
 					return CharOperation.match(pattern, name, this.isCaseSensitive);
 				case R_REGEXP_MATCH :
@@ -182,7 +190,7 @@
 	}
 	protected StringBuffer print(StringBuffer output) {
 		output.append(", "); //$NON-NLS-1$
-		if (this.typeSignatures != null && this.typeSignatures.length > 0) {
+		if (hasTypeArguments() && hasSignatures()) {
 			output.append("signature:\""); //$NON-NLS-1$
 			output.append(this.typeSignatures[0]);
 			output.append("\", "); //$NON-NLS-1$
@@ -202,10 +210,76 @@
 			output.append(" case sensitive"); //$NON-NLS-1$
 		else
 			output.append(" case insensitive"); //$NON-NLS-1$
-		if (isErasureMatch())
+		if ((this.matchCompatibility & R_ERASURE_MATCH) != 0) {
 			output.append(", erasure only"); //$NON-NLS-1$
+		}
+		if ((this.matchCompatibility & R_EQUIVALENT_MATCH) != 0) {
+			output.append(", equivalent oronly"); //$NON-NLS-1$
+		}
 		return output;
 	}
+	/**
+	 * @param typeArguments The typeArguments to set.
+	 */
+	final void setTypeArguments(char[][][] typeArguments) {
+		this.typeArguments = typeArguments;
+		// update flags
+		if (this.typeArguments != null) {
+			int length = this.typeArguments.length;
+			for (int i=0; i<length; i++) {
+				if (this.typeArguments[i] != null && this.typeArguments[i].length > 0) {
+					this.flags |= HAS_TYPE_ARGUMENTS;
+					break;
+				}
+			}
+		}
+	}
+
+	/*
+	 * Extract and store type signatures and arguments using unique key for parameterized types
+	 * and type parameters for non-generic ones
+	 */
+	void storeTypeSignaturesAndArguments(IType type) {
+		BindingKey key;
+		if (type.isResolved() && (key = new BindingKey(type.getKey())).isParameterizedType()) {
+			String signature = key.toSignature();
+			this.typeSignatures = Util.splitTypeLevelsSignature(signature);
+			setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+		} else {
+			// Scan hierachy to store type arguments at each level
+			char[][][] typeParameters = new char[10][][];
+			int ptr = -1;
+			boolean hasParameters = false;
+			try {
+				IJavaElement parent = type;
+				ITypeParameter[] parameters = null;
+				while (parent != null && parent.getElementType() == IJavaElement.TYPE) {
+					if (++ptr > typeParameters.length) {
+						System.arraycopy(typeParameters, 0, typeParameters = new char[typeParameters.length+10][][], 0, ptr);
+					}
+					IType parentType = (IType) parent;
+					parameters = parentType.getTypeParameters();
+					int length = parameters==null ? 0 : parameters.length;
+					if (length > 0) {
+						hasParameters = true;
+						typeParameters[ptr] = new char[length][];
+						for (int i=0; i<length; i++)
+							typeParameters[ptr][i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
+					}
+					parent = parent.getParent();
+				}
+			}
+			catch (JavaModelException jme) {
+				return;
+			}
+			// Store type arguments if any
+			if (hasParameters) {
+				if (++ptr < typeParameters.length)
+					System.arraycopy(typeParameters, 0, typeParameters = new char[ptr][][], 0, ptr);
+				setTypeArguments(typeParameters);
+			}
+		}
+	}
 	public final String toString() {
 		return print(new StringBuffer(30)).toString();
 	}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java
index dc9a6fd..a1bb42c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariableLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -12,7 +12,6 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.search.SearchMatch;
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
@@ -42,22 +41,25 @@
 private LocalVariable getLocalVariable() {
 	return ((LocalVariablePattern) this.pattern).localVariable;
 }
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	int offset = -1;
+	int length = -1;
 	if (reference instanceof SingleNameReference) {
-		int offset = reference.sourceStart;
-		SearchMatch match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
-		locator.report(match);
+		offset = reference.sourceStart;
+		length = reference.sourceEnd-offset+1;
 	} else if (reference instanceof QualifiedNameReference) {
 		QualifiedNameReference qNameRef = (QualifiedNameReference) reference;
 		long sourcePosition = qNameRef.sourcePositions[0];
-		int start = (int) (sourcePosition >>> 32);
-		int end = (int) sourcePosition;
-		SearchMatch match = locator.newLocalVariableReferenceMatch(element, accuracy, start, end-start+1, reference);
-		locator.report(match);
+		offset = (int) (sourcePosition >>> 32);
+		length = ((int) sourcePosition) - offset +1;
 	} else if (reference instanceof LocalDeclaration) {
 		LocalVariable localVariable = getLocalVariable();
-		int offset = localVariable.nameStart;
-		SearchMatch match = locator.newLocalVariableReferenceMatch(localVariable, accuracy, offset, localVariable.nameEnd-offset+1, reference);
+		offset = localVariable.nameStart;
+		length = localVariable.nameEnd-offset+1;
+		element = localVariable;
+	}
+	if (offset >= 0) {
+		match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, length, reference);
 		locator.report(match);
 	}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java
index 94bce6c..2f7a5fa 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/LocalVariablePattern.java
@@ -1,26 +1,28 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search.matching;
 
+import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.jdt.core.*;
 import org.eclipse.jdt.core.search.*;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.LocalVariable;
 import org.eclipse.jdt.internal.core.index.Index;
 import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
 import org.eclipse.jdt.internal.core.search.JavaSearchScope;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
 
 public class LocalVariablePattern extends VariablePattern implements IIndexConstants {
 	
@@ -32,26 +34,29 @@
 }
 public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) {
     IPackageFragmentRoot root = (IPackageFragmentRoot)this.localVariable.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
-	String path;
+	String documentPath;
+	String relativePath;
     if (root.isArchive()) {
         IType type = (IType)this.localVariable.getAncestor(IJavaElement.TYPE);
-        String filePath = (type.getFullyQualifiedName('/')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
-        path = root.getPath() + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + filePath;
+        relativePath = (type.getFullyQualifiedName('/')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
+        documentPath = root.getPath() + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + relativePath;
     } else {
-        path = this.localVariable.getPath().toString();
+		IPath path = this.localVariable.getPath();
+        documentPath = path.toString();
+		relativePath = Util.relativePath(path, 1/*remove project segment*/);
     }
 
 	if (scope instanceof JavaSearchScope) {
 		JavaSearchScope javaSearchScope = (JavaSearchScope) scope;
 		// Get document path access restriction from java search scope
 		// Note that requestor has to verify if needed whether the document violates the access restriction or not
-		AccessRestriction access = javaSearchScope.getAccessRestriction(path);
-		if (!JavaSearchScope.UNINIT_RESTRICTION.equals(access)) { // scope encloses the path
-			if (!requestor.acceptIndexMatch(path, this, participant, access)) 
+		AccessRuleSet access = javaSearchScope.getAccessRuleSet(relativePath, index.containerPath);
+		if (access != JavaSearchScope.NOT_ENCLOSED) { // scope encloses the path
+			if (!requestor.acceptIndexMatch(documentPath, this, participant, access)) 
 				throw new OperationCanceledException();
 		}
-	} else if (scope.encloses(path)) {
-		if (!requestor.acceptIndexMatch(path, this, participant, null)) 
+	} else if (scope.encloses(documentPath)) {
+		if (!requestor.acceptIndexMatch(documentPath, this, participant, null)) 
 			throw new OperationCanceledException();
 	}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 7126ff7..219672c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,6 +14,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.zip.ZipFile;
 
 import org.eclipse.core.resources.IResource;
@@ -46,9 +47,11 @@
 import org.eclipse.jdt.internal.compiler.parser.*;
 import org.eclipse.jdt.internal.compiler.problem.*;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues;
+import org.eclipse.jdt.internal.compiler.util.Messages;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver;
+import org.eclipse.jdt.internal.core.BinaryMember;
 import org.eclipse.jdt.internal.core.BinaryType;
 import org.eclipse.jdt.internal.core.ClassFile;
 import org.eclipse.jdt.internal.core.CompilationUnit;
@@ -120,10 +123,12 @@
  */
 public class LocalDeclarationVisitor extends ASTVisitor {
 	IJavaElement enclosingElement;
+	Binding enclosingElementBinding;
 	MatchingNodeSet nodeSet;
 	HashtableOfIntValues occurrencesCounts = new HashtableOfIntValues(); // key = class name (char[]), value = occurrenceCount (int)
-	public LocalDeclarationVisitor(IJavaElement enclosingElement, MatchingNodeSet nodeSet) {
+	public LocalDeclarationVisitor(IJavaElement enclosingElement, Binding enclosingElementBinding, MatchingNodeSet nodeSet) {
 		this.enclosingElement = enclosingElement;
+		this.enclosingElementBinding = enclosingElementBinding;
 		this.nodeSet = nodeSet;
 	}
 	public boolean visit(TypeDeclaration typeDeclaration, BlockScope unused) {
@@ -143,17 +148,17 @@
 			occurrencesCounts.put(simpleName, occurrenceCount);
 			if (typeDeclaration.allocation == null || typeDeclaration.allocation.enumConstant == null) {
 				if ((typeDeclaration.bits & ASTNode.IsAnonymousTypeMASK) != 0) {				
-					reportMatching(typeDeclaration, enclosingElement, -1, nodeSet, occurrenceCount);
+					reportMatching(typeDeclaration, this.enclosingElement, -1, nodeSet, occurrenceCount);
 				} else {
 					Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeDeclaration);
-					reportMatching(typeDeclaration, enclosingElement, level != null ? level.intValue() : -1, nodeSet, occurrenceCount);
+					reportMatching(typeDeclaration, this.enclosingElement, level != null ? level.intValue() : -1, nodeSet, occurrenceCount);
 				}
 			} else {
 				Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeDeclaration);
 				if (level != null) {
 					FieldDeclaration enumConstant = typeDeclaration.allocation.enumConstant;
 					int offset = enumConstant.sourceStart;
-					SearchMatch match = newDeclarationMatch(enclosingElement, level.intValue(), offset, enumConstant.sourceEnd-offset+1);
+					SearchMatch match = newDeclarationMatch(this.enclosingElement, this.enclosingElementBinding, level.intValue(), offset, enumConstant.sourceEnd-offset+1);
 					report(match);
 				}
 			}
@@ -255,7 +260,7 @@
 	IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent();
 	try {
 		if (!root.isArchive())
-			return ClassFileReader.read(type.getPath().toOSString());
+			return ClassFileReader.read(type.getResource().getLocation().toOSString());
 
 		IPath zipPath = root.isExternal() ? root.getPath() : root.getResource().getLocation();
 		if (zipPath == null) return null; // location is null
@@ -410,7 +415,7 @@
 		throw new OperationCanceledException();
 
 	try {
-		if (SearchBasicEngine.VERBOSE)
+		if (BasicSearchEngine.VERBOSE)
 			System.out.println("Parsing " + possibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
 
 		this.parser.nodeSet = possibleMatch.nodeSet;
@@ -640,6 +645,42 @@
 protected boolean encloses(IJavaElement element) {
 	return element != null && this.scope.encloses(element);
 }
+/* (non-Javadoc)
+ * Return info about last type argument of a parameterized type reference.
+ * These info are made of concatenation of 2 int values which are respectively
+ *  depth and end position of the last type argument.
+ * For example, this method will return 0x300000020 for type ref List<List<List<String>>>
+ * if end position of type reference "String" equals 32.
+ */
+private long findLastTypeArgumentInfo(TypeReference typeRef) {
+	// Get last list of type arguments for parameterized qualified type reference
+	TypeReference lastTypeArgument = typeRef;
+	int depth = 0;
+	while (true) {
+		TypeReference[] lastTypeArguments = null;
+		if (lastTypeArgument instanceof ParameterizedQualifiedTypeReference) {
+			ParameterizedQualifiedTypeReference pqtRef = (ParameterizedQualifiedTypeReference) lastTypeArgument;
+			for (int i=pqtRef.typeArguments.length-1; i>=0 && lastTypeArguments==null; i--) {
+				lastTypeArguments = pqtRef.typeArguments[i];
+			}
+		}
+		// Get last type argument for single type reference of last list of argument of parameterized qualified type reference
+		TypeReference last = null;
+		if (lastTypeArgument instanceof ParameterizedSingleTypeReference || lastTypeArguments != null) {
+			if (lastTypeArguments == null) {
+				lastTypeArguments = ((ParameterizedSingleTypeReference)lastTypeArgument).typeArguments;
+			}
+			for (int i=lastTypeArguments.length-1; i>=0 && last==null; i++) {
+				last = lastTypeArguments[i];
+			}
+		}
+		if (last == null) break;
+		depth++;
+		lastTypeArgument = last;
+	}
+	// Current type reference is not parameterized. So, it is the last type argument
+	return (((long) depth) << 32) + lastTypeArgument.sourceEnd;
+}
 protected IBinaryType getBinaryInfo(ClassFile classFile, IResource resource) throws CoreException {
 	BinaryType binaryType = (BinaryType) classFile.getType();
 	if (classFile.isOpen())
@@ -732,7 +773,6 @@
 		return null;
 	}
 	//	Get binding from unit scope
-	MethodBinding methodBinding = null;
 	String typeName = method.getDeclaringType().getElementName();
 	TypeBinding declaringTypeBinding = getType(typeName, typeName.toCharArray());
 	if (declaringTypeBinding != null) {
@@ -741,15 +781,54 @@
 		}
 		if (!declaringTypeBinding.isBaseType()) {
 			String[] parameterTypes = method.getParameterTypes();
-			int length = parameterTypes.length;
-			TypeBinding[] parameters = new TypeBinding[length];
-			for (int i=0;  i<length; i++) {
-				parameters[i] = this.unitScope.getType(Signature.toCharArray(parameterTypes[i].toCharArray()));
+			int paramTypeslength = parameterTypes.length;
+			char[][] paramTypesChars = new char[paramTypeslength][];
+			for (int i=0;  i<paramTypeslength; i++) {
+				paramTypesChars[i] = Signature.toCharArray(parameterTypes[i].toCharArray());
 			}
 			ReferenceBinding referenceBinding = (ReferenceBinding) declaringTypeBinding;
-			methodBinding = referenceBinding.getExactMethod(method.getElementName().toCharArray(), parameters);
-			this.bindings.put(method, methodBinding);
-			return methodBinding;
+			MethodBinding[] methods = referenceBinding.getMethods(method.getElementName().toCharArray());
+			int methodsLength = methods.length;
+			TypeVariableBinding[] refTypeVariables = referenceBinding.typeVariables();
+			int typeVarLength = refTypeVariables==null ? 0 : refTypeVariables.length;
+			for (int i=0; i<methodsLength; i++) {
+				TypeBinding[] methodParameters = methods[i].parameters;
+				int paramLength = methodParameters==null ? 0 : methodParameters.length;
+				TypeVariableBinding[] methodTypeVariables = methods[i].typeVariables;
+				int methTypeVarLength = methodTypeVariables==null ? 0 : methodTypeVariables.length;
+				boolean found = paramLength == paramTypeslength;
+				if (found) {
+					for (int p=0; found && p<paramLength; p++) {
+						if (CharOperation.equals(methodParameters[p].erasure().shortReadableName(), paramTypesChars[p])) {
+							// param erasure match
+						} else {
+							// type variable
+							boolean foundVar = true;
+							for (int v=0; foundVar && v<typeVarLength; v++) {
+								if (!CharOperation.equals(refTypeVariables[v].sourceName, paramTypesChars[p])) {
+									foundVar = false;
+								}
+							}
+							if (!foundVar) {
+								foundVar = true;
+								for (int v=0; foundVar && v<methTypeVarLength; v++) {
+									if (!CharOperation.equals(methodTypeVariables[v].sourceName, paramTypesChars[p])) {
+										foundVar = false;
+									}
+								}
+								if (!foundVar) found = false;
+							}
+						}
+					}
+				}
+				if (found) {
+					this.bindings.put(method, methods[i]);
+					return methods[i];
+				}
+			}
+//			methodBinding = referenceBinding.getExactMethod(method.getElementName().toCharArray(), parameters);
+//			this.bindings.put(method, methodBinding);
+//			return methodBinding;
 		}
 	}
 	this.bindings.put(method, new ProblemMethodBinding(method.getElementName().toCharArray(), null, ProblemReasons.NotFound));
@@ -782,7 +861,9 @@
 		: (INameEnvironment) new JavaSearchNameEnvironment(project, this.workingCopies);
 
 	// create lookup environment
-	this.options = new CompilerOptions(project.getOptions(true));
+	Map map = project.getOptions(true);
+	map.put(CompilerOptions.OPTION_TaskTags, ""); //$NON-NLS-1$
+	this.options = new CompilerOptions(map);
 	ProblemReporter problemReporter =
 		new ProblemReporter(
 			DefaultErrorHandlingPolicies.proceedWithAllProblems(),
@@ -863,11 +944,13 @@
 				if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
 			}
 			if (this.options.verbose)
-				System.out.println(Util.bind("compilation.done", //$NON-NLS-1$
-					new String[] {
-						String.valueOf(i + 1),
-						String.valueOf(this.numberOfMatches),
-						new String(possibleMatch.parsedUnit.getFileName())}));
+				System.out.println(
+					Messages.bind(Messages.compilation_done,
+						new String[] {
+							String.valueOf(i + 1),
+							String.valueOf(this.numberOfMatches),
+							new String(possibleMatch.parsedUnit.getFileName())
+						}));
 			// cleanup compilation unit result
 			possibleMatch.cleanUp();
 		}
@@ -896,7 +979,7 @@
  */
 public void locateMatches(SearchDocument[] searchDocuments) throws CoreException {
 	int docsLength = searchDocuments.length;
-	if (SearchBasicEngine.VERBOSE) {
+	if (BasicSearchEngine.VERBOSE) {
 		System.out.println("Locating matches in documents ["); //$NON-NLS-1$
 		for (int i = 0; i < docsLength; i++)
 			System.out.println("\t" + searchDocuments[i]); //$NON-NLS-1$
@@ -1039,7 +1122,7 @@
 			SearchDocument document = participant.getDocument(focus.getPath().toString());
 			this.currentPossibleMatch = new PossibleMatch(this, focus.getResource(), null, document);
 			if (encloses(focus)) {
-				SearchMatch match = newDeclarationMatch(focus, SearchMatch.A_ACCURATE, -1, -1);
+				SearchMatch match = newDeclarationMatch(focus.getAncestor(IJavaElement.PACKAGE_FRAGMENT), null/*no binding*/, SearchMatch.A_ACCURATE, -1, -1);
 				report(match);
 			}
 			return;
@@ -1081,7 +1164,7 @@
 						this.currentPossibleMatch = new PossibleMatch(this, resource, null, document);
 						try {
 							if (encloses(pkg)) {
-								SearchMatch match = newDeclarationMatch(pkg, SearchMatch.A_ACCURATE, -1, -1);
+								SearchMatch match = newDeclarationMatch(pkg, null/*no binding*/, SearchMatch.A_ACCURATE, -1, -1);
 								report(match);
 							}
 						} catch (JavaModelException e) {
@@ -1108,12 +1191,18 @@
 	// iterate type lookup in each package fragment
 	char[] sourceName = typeBinding.qualifiedSourceName();
 	String typeName = new String(sourceName);
+	int acceptFlag = 0;
+	if (typeBinding.isAnnotationType()) {
+		acceptFlag = NameLookup.ACCEPT_ANNOTATIONS;
+	} else if (typeBinding.isEnum()) {
+		acceptFlag = NameLookup.ACCEPT_ENUMS;
+	} else if (typeBinding.isInterface()) {
+		acceptFlag = NameLookup.ACCEPT_INTERFACES;
+	} else if (typeBinding.isClass()) {
+		acceptFlag = NameLookup.ACCEPT_CLASSES;
+	}
 	for (int i = 0, length = pkgs == null ? 0 : pkgs.length; i < length; i++) {
-		IType type = this.nameLookup.findType(
-			typeName,
-			pkgs[i], 
-			false, 
-			typeBinding.isClass() ? NameLookup.ACCEPT_CLASSES : NameLookup.ACCEPT_INTERFACES); // TODO (frederic) should distinguish ENUMS and ANNOTATIONS
+		IType type = this.nameLookup.findType(typeName, pkgs[i],  false,  acceptFlag);
 		if (type != null) return type;
 	}
 
@@ -1134,16 +1223,18 @@
 }
 public SearchMatch newDeclarationMatch(
 		IJavaElement element,
+		Binding binding,
 		int accuracy,
 		int offset,  
 		int length) {
 	SearchParticipant participant = getParticipant(); 
 	IResource resource = this.currentPossibleMatch.resource;
-	return newDeclarationMatch(element, accuracy, offset, length, participant, resource);
+	return newDeclarationMatch(element, binding, accuracy, offset, length, participant, resource);
 }
 
 public SearchMatch newDeclarationMatch(
 		IJavaElement element,
+		Binding binding,
 		int accuracy,
 		int offset,  
 		int length,
@@ -1153,15 +1244,17 @@
 		case IJavaElement.PACKAGE_FRAGMENT:
 			return new PackageDeclarationMatch(element, accuracy, offset, length, participant, resource);
 		case IJavaElement.TYPE:
-			return new TypeDeclarationMatch(element, accuracy, offset, length, participant, resource);
+			return new TypeDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource);
 		case IJavaElement.FIELD:
-			return new FieldDeclarationMatch(element, accuracy, offset, length, participant, resource);
+			return new FieldDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource);
 		case IJavaElement.METHOD:
-			return new MethodDeclarationMatch(element, accuracy, offset, length, participant, resource);
+			return new MethodDeclarationMatch(binding == null ? element : ((JavaElement) element).resolved(binding), accuracy, offset, length, participant, resource);
 		case IJavaElement.LOCAL_VARIABLE:
 			return new LocalVariableDeclarationMatch(element, accuracy, offset, length, participant, resource);
 		case IJavaElement.PACKAGE_DECLARATION:
 			return new PackageDeclarationMatch(element, accuracy, offset, length, participant, resource);
+		case IJavaElement.TYPE_PARAMETER:
+			return new TypeParameterDeclarationMatch(element, accuracy, offset, length, participant, resource);
 		default:
 			return null;
 	}
@@ -1169,6 +1262,7 @@
 
 public SearchMatch newFieldReferenceMatch(
 		IJavaElement enclosingElement,
+		Binding enclosingBinding,
 		int accuracy,
 		int offset,  
 		int length,
@@ -1180,6 +1274,8 @@
 	boolean insideDocComment = (bits & ASTNode.InsideJavadoc) != 0;
 	SearchParticipant participant = getParticipant(); 
 	IResource resource = this.currentPossibleMatch.resource;
+	if (enclosingBinding != null)
+		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
 	return new FieldReferenceMatch(enclosingElement, accuracy, offset, length, isReadAccess, isWriteAccess, insideDocComment, participant, resource);
 }
 
@@ -1201,6 +1297,7 @@
 
 public SearchMatch newMethodReferenceMatch(
 		IJavaElement enclosingElement,
+		Binding enclosingBinding,
 		int accuracy,
 		int offset,  
 		int length,
@@ -1210,6 +1307,8 @@
 	SearchParticipant participant = getParticipant(); 
 	IResource resource = this.currentPossibleMatch.resource;
 	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
+	if (enclosingBinding != null)
+		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
 	return new MethodReferenceMatch(enclosingElement, accuracy, offset, length, isConstructor, isSynthetic, insideDocComment, participant, resource);
 }
 
@@ -1225,8 +1324,22 @@
 	return new PackageReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
 }
 
+public SearchMatch newTypeParameterReferenceMatch(
+		IJavaElement enclosingElement,
+		int accuracy,
+		int offset,  
+		int length,
+		ASTNode reference) {
+	int bits = reference.bits;
+	boolean insideDocComment = (bits & ASTNode.InsideJavadoc) != 0;
+	SearchParticipant participant = getParticipant(); 
+	IResource resource = this.currentPossibleMatch.resource;
+	return new TypeParameterReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
+}
+
 public SearchMatch newTypeReferenceMatch(
 		IJavaElement enclosingElement,
+		Binding enclosingBinding,
 		int accuracy,
 		int offset,  
 		int length,
@@ -1234,19 +1347,17 @@
 	SearchParticipant participant = getParticipant(); 
 	IResource resource = this.currentPossibleMatch.resource;
 	boolean insideDocComment = (reference.bits & ASTNode.InsideJavadoc) != 0;
+	if (enclosingBinding != null)
+		enclosingElement = ((JavaElement) enclosingElement).resolved(enclosingBinding);
 	return new TypeReferenceMatch(enclosingElement, accuracy, offset, length, insideDocComment, participant, resource);
 }
 
 public SearchMatch newTypeReferenceMatch(
 		IJavaElement enclosingElement,
+		Binding enclosingBinding,
 		int accuracy,
-		int offset,  
-		int length,
-		int rule,
 		ASTNode reference) {
-	SearchMatch match = newTypeReferenceMatch(enclosingElement, accuracy, offset, length, reference);
-	match.setMatchRule(rule);
-	return match;
+	return newTypeReferenceMatch(enclosingElement, enclosingBinding, accuracy, reference.sourceStart, reference.sourceEnd-reference.sourceStart+1, reference);
 }
 
 /*
@@ -1270,7 +1381,7 @@
 		getMethodBodies(unit);
 
 		if (bindingsWereCreated && ((InternalSearchPattern)this.pattern).mustResolve && unit.types != null) {
-			if (SearchBasicEngine.VERBOSE)
+			if (BasicSearchEngine.VERBOSE)
 				System.out.println("Resolving " + this.currentPossibleMatch.openable.toStringWithAncestors()); //$NON-NLS-1$
 
 			reduceParseTree(unit);
@@ -1278,8 +1389,6 @@
 			if (unit.scope != null) {
 				// fault in fields & methods
 				unit.scope.faultInTypes();
-				// verify inherited methods
-				unit.scope.verifyMethods(this.lookupEnvironment.methodVerifier());
 			}
 			unit.resolve();
 
@@ -1339,30 +1448,33 @@
 
 protected void report(SearchMatch match) throws CoreException {
 	long start = -1;
-	if (SearchBasicEngine.VERBOSE) {
+	if (BasicSearchEngine.VERBOSE) {
 		start = System.currentTimeMillis();
 		System.out.println("Reporting match"); //$NON-NLS-1$
 		System.out.println("\tResource: " + match.getResource()); //$NON-NLS-2$//$NON-NLS-1$
 		System.out.println("\tPositions: [offset=" + match.getOffset() + ", length=" + match.getLength() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		if (this.parser != null && match.getOffset() > 0 && match.getLength() > 0 && !(match.getElement() instanceof BinaryMember)) {
+			String selection = new String(this.parser.scanner.source, match.getOffset(), match.getLength());
+			System.out.println("\tSelection: -->" + selection + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
+		}
 		System.out.println("\tJava element: " + ((JavaElement)match.getElement()).toStringWithAncestors()); //$NON-NLS-1$
 		System.out.println(match.getAccuracy() == SearchMatch.A_ACCURATE
 			? "\tAccuracy: EXACT_MATCH" //$NON-NLS-1$
 			: "\tAccuracy: POTENTIAL_MATCH"); //$NON-NLS-1$
-		System.out.print("\tMatch rule: "); //$NON-NLS-1$
-		if ((match.getMatchRule() & SearchPattern.R_EQUIVALENT_MATCH) != 0) {
-			if ((match.getMatchRule() & SearchPattern.R_ERASURE_MATCH) != 0) {
-				System.out.println("EQUIVALENT + ERASURE"); //$NON-NLS-1$
-			} else {
-				System.out.println("EQUIVALENT"); //$NON-NLS-1$
-			}
-		} else if ((match.getMatchRule() & SearchPattern.R_ERASURE_MATCH) != 0) {
+		System.out.print("\tRule: "); //$NON-NLS-1$
+		if (match.isExact()) {
+			System.out.println("EXACT"); //$NON-NLS-1$
+		} else if (match.isEquivalent()) {
+			System.out.println("EQUIVALENT"); //$NON-NLS-1$
+		} else if (match.isErasure()) {
 			System.out.println("ERASURE"); //$NON-NLS-1$
 		} else {
-			System.out.println("PERFECT"); //$NON-NLS-1$
+			System.out.println("INVALID RULE"); //$NON-NLS-1$
 		}
+		System.out.println("\tRaw: "+match.isRaw()); //$NON-NLS-1$
 	}
 	this.requestor.acceptSearchMatch(match);
-	if (SearchBasicEngine.VERBOSE)
+	if (BasicSearchEngine.VERBOSE)
 		this.resultCollectorTime += System.currentTimeMillis()-start;
 }
 /**
@@ -1370,17 +1482,13 @@
  * in the source and reports a reference to this this qualified name
  * to the search requestor.
  */
-protected void reportAccurateTypeReference(ASTNode typeRef, char[] name, IJavaElement element, int accuracy) throws CoreException {
-	reportAccurateTypeReference(typeRef, name, element, accuracy, SearchPattern.R_EXACT_MATCH);
-}
-protected void reportAccurateTypeReference(ASTNode typeRef, char[] name, IJavaElement element, int accuracy, int rule) throws CoreException {
-	if (accuracy == -1) return;
-	if (!encloses(element)) return;
-
+protected void reportAccurateTypeReference(SearchMatch match, ASTNode typeRef, char[] name) throws CoreException {
+	if (match.getRule() == 0) return;
+	if (!encloses((IJavaElement)match.getElement())) return;
+	
+	// Compute source positions of the qualified reference 
 	int sourceStart = typeRef.sourceStart;
 	int sourceEnd = typeRef.sourceEnd;
-	
-	// compute source positions of the qualified reference 
 	Scanner scanner = this.parser.scanner;
 	scanner.setSource(this.currentPossibleMatch.getContents());
 	scanner.resetTo(sourceStart, sourceEnd);
@@ -1396,24 +1504,84 @@
 		}
 		if (token == TerminalTokens.TokenNameIdentifier && this.pattern.matchesName(name, scanner.getCurrentTokenSource())) {
 			int length = scanner.currentPosition-currentPosition;
-			SearchMatch match = newTypeReferenceMatch(element, accuracy, currentPosition, length, rule, typeRef);
+			match.setOffset(currentPosition);
+			match.setLength(length);
 			report(match);
 			return;
 		}
 	} while (token != TerminalTokens.TokenNameEOF);
-	SearchMatch match = newTypeReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, rule, typeRef);
+
+	//	Report match
+	match.setOffset(sourceStart);
+	match.setLength(sourceEnd-sourceStart+1);
 	report(match);
 }
 
 /**
- * @since 3.1
  * Finds the accurate positions of the sequence of tokens given by qualifiedName
  * in the source and reports a reference to this parameterized type name
  * to the search requestor.
+ * @since 3.1
  */
-protected void reportAccurateParameterizedTypeReference(TypeReference typeRef, int start, int index, TypeReference[] typeArguments, IJavaElement element, int accuracy, int rule) throws CoreException {
-	if (accuracy == -1) return;
-	if (!encloses(element)) return;
+protected void reportAccurateParameterizedMethodReference(SearchMatch match, ASTNode statement, TypeReference[] typeArguments) throws CoreException {
+	if (match.getRule() == 0) return;
+	if (!encloses((IJavaElement)match.getElement())) return;
+
+	// If there's type arguments, look for end (ie. char '>') of last one.
+	int start = match.getOffset();
+	if (typeArguments != null && typeArguments.length > 0) {
+		boolean isErasureMatch= (pattern instanceof OrPattern) ? ((OrPattern)pattern).isErasureMatch() : ((JavaSearchPattern)pattern).isErasureMatch();
+		if (!isErasureMatch) {
+			
+			// Initialize scanner
+			Scanner scanner = this.parser.scanner;
+			char[] source = this.currentPossibleMatch.getContents();
+			scanner.setSource(source);
+
+			// Search previous opening '<'
+			start = typeArguments[0].sourceStart;
+			int end = statement.sourceEnd;
+			scanner.resetTo(start, end);
+			int lineStart = start;
+			try {
+				linesUp: while (true) {
+					while (scanner.source[scanner.currentPosition] != '\n') {
+						scanner.currentPosition--;
+						if (scanner.currentPosition == 0) break linesUp;
+					}
+					lineStart = scanner.currentPosition+1;
+					scanner.resetTo(lineStart, end);
+					while (!scanner.atEnd()) {
+						if (scanner.getNextToken() == TerminalTokens.TokenNameLESS) {
+							start = scanner.getCurrentTokenStartPosition();
+							break linesUp;
+						}
+					}
+					end = lineStart - 2;
+					scanner.currentPosition = end;
+				}
+			}
+			catch (InvalidInputException ex) {
+				// give up
+			}
+	 	}
+	}
+	
+	// Report match
+	match.setOffset(start);
+	match.setLength(statement.sourceEnd-start+1);
+	report(match);
+}
+
+/**
+ * Finds the accurate positions of the sequence of tokens given by qualifiedName
+ * in the source and reports a reference to this parameterized type name
+ * to the search requestor.
+ * @since 3.1
+ */
+protected void reportAccurateParameterizedTypeReference(SearchMatch match, TypeReference typeRef, int index, TypeReference[] typeArguments) throws CoreException {
+	if (match.getRule() == 0) return;
+	if (!encloses((IJavaElement)match.getElement())) return;
 
 	// If there's type arguments, look for end (ie. char '>') of last one.
 	int end = typeRef.sourceEnd;
@@ -1423,9 +1591,9 @@
 		char[] source = this.currentPossibleMatch.getContents();
 		scanner.setSource(source);
 
-		
-		JavaSearchPattern javaSearchPattern = (JavaSearchPattern)this.pattern;
-		if (javaSearchPattern.isErasureMatch || javaSearchPattern.typeSignatures == null) {
+		boolean shouldMatchErasure= (pattern instanceof OrPattern) ? ((OrPattern)pattern).isErasureMatch() : ((JavaSearchPattern)pattern).isErasureMatch();
+		boolean hasSignatures = (pattern instanceof OrPattern) ? ((OrPattern)pattern).hasSignatures() : ((JavaSearchPattern)pattern).hasSignatures();
+		if (shouldMatchErasure || !hasSignatures) {
 			// if pattern is erasure only, then select the end of the reference
 			if (typeRef instanceof QualifiedTypeReference && index >= 0) {
 				long[] positions = ((QualifiedTypeReference) typeRef).sourcePositions;
@@ -1439,7 +1607,9 @@
 			int depth = 0;
 			for (int i=typeArguments.length-1; i>=0; i--) {
 				if (typeArguments[i] != null) {
-					depth = resetScannerAfterLastTypeArgumentEnd(typeArguments[i], scanner, depth)+1;
+					long lastTypeArgInfo = findLastTypeArgumentInfo(typeArguments[i]);
+					depth = (int) (lastTypeArgInfo >>> 32)+1;
+					scanner.resetTo(((int)lastTypeArgInfo)+1, scanner.eofPosition-1);
 					break;
 				}
 			}
@@ -1457,61 +1627,17 @@
 	}
 	
 	// Report match
-	SearchMatch match = newTypeReferenceMatch(element, accuracy, start, end-start+1, rule, typeRef);
+	match.setLength(end-match.getOffset()+1);
 	report(match);
 }
-/* (non-Javadoc)
- * Reset scanner after last type argument end. This may be called recursively for nested parameterized
- * type arguments.
- * Returns depth of nesting for the last argument.
- */
-private int resetScannerAfterLastTypeArgumentEnd(TypeReference typeRef, Scanner scanner, int depth) {
-	// Default end is current type argument end
-	int end = typeRef.sourceEnd;
-	// Get last list of type arguments for parameterized qualified type reference
-	TypeReference[] typeArguments = null;
-	if (typeRef instanceof ParameterizedQualifiedTypeReference) {
-		ParameterizedQualifiedTypeReference pqtRef = (ParameterizedQualifiedTypeReference) typeRef;
-		TypeReference[] last = null;
-		for (int i=pqtRef.typeArguments.length-1; i>=0 && last==null; i--) {
-			last = pqtRef.typeArguments[i];
-		}
-		// If no children arguments then current type reference is the last type argument
-		if (last == null) {
-			scanner.resetTo(end+1, scanner.eofPosition-1);
-			return depth;
-		}
-		typeArguments = last;
-	}
-	// Get last type argument for single type reference of last list of argument of parameterized qualified type reference
-	if (typeRef instanceof ParameterizedSingleTypeReference || typeArguments != null) {
-		if (typeArguments == null) {
-			typeArguments = ((ParameterizedSingleTypeReference)typeRef).typeArguments;
-		}
-		TypeReference last = null;
-		for (int i=typeArguments.length-1; i>=0 && last==null; i++) {
-			last = typeArguments[i];
-		}
-		// If no child argument then current type reference is the last type argument
-		if (last == null) {
-			scanner.resetTo(end+1, scanner.eofPosition-1);
-			return depth;
-		}
-		// Loop on last type argument to find its last type argument...
-		return resetScannerAfterLastTypeArgumentEnd(last, scanner, depth+1);
-	}
-	// Current type reference is not parameterized. So, it is the last type argument
-	scanner.resetTo(end+1, scanner.eofPosition-1);
-	return depth;
-}
 /**
  * Finds the accurate positions of each valid token in the source and
  * reports a reference to this token to the search requestor.
  * A token is valid if it has an accuracy which is not -1.
  */
-protected void reportAccurateFieldReference(QualifiedNameReference qNameRef, IJavaElement element, int[] accuracies) throws CoreException {
-	if (!encloses(element)) return;
-	
+protected void reportAccurateFieldReference(SearchMatch[] matches, QualifiedNameReference qNameRef) throws CoreException {
+	int matchesLength = matches == null ? 0 : matches.length;
+
 	int sourceStart = qNameRef.sourceStart;
 	int sourceEnd = qNameRef.sourceEnd;
 	char[][] tokens = qNameRef.tokens;
@@ -1520,13 +1646,14 @@
 	Scanner scanner = this.parser.scanner;
 	scanner.setSource(this.currentPossibleMatch.getContents());
 	scanner.resetTo(sourceStart, sourceEnd);
+	int sourceLength = sourceEnd-sourceStart+1;
 
 	int refSourceStart = -1, refSourceEnd = -1;
 	int length = tokens.length;
 	int token = -1;
 	int previousValid = -1;
 	int i = 0;
-	int accuracyIndex = 0;
+	int index = 0;
 	do {
 		int currentPosition = scanner.currentPosition;
 		// read token
@@ -1556,25 +1683,30 @@
 				// ignore
 			}
 		}
-		if (accuracies[accuracyIndex] != -1) {
+		SearchMatch match = matches[index];
+		if (match != null && match.getRule() != 0) {
+			if (!encloses((IJavaElement)match.getElement())) return;
 			// accept reference
 			if (refSourceStart != -1) {
-				SearchMatch match = newFieldReferenceMatch(element, accuracies[accuracyIndex], refSourceStart, refSourceEnd-refSourceStart+1, qNameRef);
+				match.setOffset(refSourceStart);
+				match.setLength(refSourceEnd-refSourceStart+1);
 				report(match);
 			} else {
-				SearchMatch match = newFieldReferenceMatch(element, accuracies[accuracyIndex], sourceStart, sourceEnd-sourceStart+1, qNameRef);
+				match.setOffset(sourceStart);
+				match.setLength(sourceLength);
 				report(match);
 			}
 			i = 0;
 		}
 		refSourceStart = -1;
 		previousValid = -1;
-		if (accuracyIndex < accuracies.length - 1)
-			accuracyIndex++;
+		if (index < matchesLength - 1) {
+			index++;
+		}
 	} while (token != TerminalTokens.TokenNameEOF);
 
 }
-protected void reportBinaryMemberDeclaration(IResource resource, IMember binaryMember, IBinaryType info, int accuracy) throws CoreException {
+protected void reportBinaryMemberDeclaration(IResource resource, IMember binaryMember, Binding binaryMemberBinding, IBinaryType info, int accuracy) throws CoreException {
 	ClassFile classFile = (ClassFile) binaryMember.getClassFile();
 	ISourceRange range = classFile.isOpen() ? binaryMember.getNameRange() : SourceMapper.fgUnknownRange;
 	if (range.getOffset() == -1) {
@@ -1590,7 +1722,7 @@
 		}
 	}
 	if (resource == null) resource =  this.currentPossibleMatch.resource;
-	SearchMatch match = newDeclarationMatch(binaryMember, accuracy, range.getOffset(), range.getLength(), getParticipant(), resource);
+	SearchMatch match = newDeclarationMatch(binaryMember, binaryMemberBinding, accuracy, range.getOffset(), range.getLength(), getParticipant(), resource);
 	report(match);
 }
 /**
@@ -1615,7 +1747,7 @@
 			}
 			if (encloses(enclosingElement)) {
 				int length = scanner.currentPosition - nameSourceStart;
-				SearchMatch match = this.patternLocator.newDeclarationMatch(method, enclosingElement, accuracy, length, this);
+				SearchMatch match = this.patternLocator.newDeclarationMatch(method, enclosingElement, method.binding, accuracy, length, this);
 				report(match);
 			}
 		}
@@ -1625,7 +1757,7 @@
 	if ((method.bits & ASTNode.HasLocalTypeMASK) != 0) {
 		if (enclosingElement == null)
 			enclosingElement = createHandle(method, parent);
-		LocalDeclarationVisitor localDeclarationVisitor = new LocalDeclarationVisitor(enclosingElement, nodeSet);
+		LocalDeclarationVisitor localDeclarationVisitor = new LocalDeclarationVisitor(enclosingElement, method.binding, nodeSet);
 		try {
 			method.traverse(localDeclarationVisitor, (ClassScope) null);
 		} catch (WrappedCoreException e) {
@@ -1641,7 +1773,7 @@
 			if (level != null) {
 				if (enclosingElement == null)
 					enclosingElement = createHandle(method, parent);
-				this.patternLocator.matchReportReference(typeRef, enclosingElement, level.intValue(), this);
+				this.patternLocator.matchReportReference(typeRef, enclosingElement, method.binding, level.intValue(), this);
 			}
 		}
 	}
@@ -1657,7 +1789,7 @@
 					for (int i = 0, l = nodes.length; i < l; i++) {
 						ASTNode node = nodes[i];
 						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
-						this.patternLocator.matchReportReference(node, enclosingElement, level.intValue(), this);
+						this.patternLocator.matchReportReference(node, enclosingElement, method.binding, level.intValue(), this);
 					}
 					return;
 				}
@@ -1712,7 +1844,7 @@
 				ImportReference importRef = imports[i];
 				Integer level = (Integer) nodeSet.matchingNodes.removeKey(importRef);
 				if (level != null)
-					this.patternLocator.matchReportImportRef(importRef, null, createImportHandle(importRef), level.intValue(), this);
+					this.patternLocator.matchReportImportRef(importRef, null/*no binding*/, createImportHandle(importRef), level.intValue(), this);
 			}
 		}
 	}
@@ -1738,7 +1870,7 @@
 		enclosingElement = createHandle(field, type, parent);
 		if (encloses(enclosingElement)) {
 			int offset = field.sourceStart;
-			SearchMatch match = newDeclarationMatch(enclosingElement, accuracy, offset, field.sourceEnd-offset+1);
+			SearchMatch match = newDeclarationMatch(enclosingElement, field.binding, accuracy, offset, field.sourceEnd-offset+1);
 			report(match);
 		}
 	}
@@ -1747,7 +1879,7 @@
 	if ((field.bits & ASTNode.HasLocalTypeMASK) != 0) {
 		if (enclosingElement == null)
 			enclosingElement = createHandle(field, type, parent);
-		LocalDeclarationVisitor localDeclarationVisitor = new LocalDeclarationVisitor(enclosingElement, nodeSet);
+		LocalDeclarationVisitor localDeclarationVisitor = new LocalDeclarationVisitor(enclosingElement, field.binding, nodeSet);
 		try {
 			field.traverse(localDeclarationVisitor, null);
 		} catch (WrappedCoreException e) {
@@ -1763,7 +1895,7 @@
 			if (level != null) {
 				if (enclosingElement == null)
 					enclosingElement = createHandle(field, type, parent);
-				this.patternLocator.matchReportReference(typeRef, enclosingElement, level.intValue(), this);
+				this.patternLocator.matchReportReference(typeRef, enclosingElement, field.binding, level.intValue(), this);
 			}
 		}
 	}
@@ -1783,7 +1915,7 @@
 					for (int i = 0, l = nodes.length; i < l; i++) {
 						ASTNode node = nodes[i];
 						Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
-						this.patternLocator.matchReportReference(node, enclosingElement, level.intValue(), this);
+						this.patternLocator.matchReportReference(node, enclosingElement, field.binding, level.intValue(), this);
 					}
 			}
 		}
@@ -1812,7 +1944,7 @@
 	// report the type declaration
 	if (accuracy > -1 && encloses(enclosingElement)) {
 		int offset = type.sourceStart;
-		SearchMatch match = this.patternLocator.newDeclarationMatch(type, enclosingElement, accuracy, type.sourceEnd-offset+1, this);
+		SearchMatch match = this.patternLocator.newDeclarationMatch(type, enclosingElement, type.binding, accuracy, type.sourceEnd-offset+1, this);
 		report(match);
 	}
 
@@ -1823,17 +1955,25 @@
 		for (int i=0, l=type.typeParameters.length; i<l; i++) {
 			TypeParameter typeParameter = type.typeParameters[i];
 			if (typeParameter != null) {
+				Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter);
+				if (level != null && matchedClassContainer) {
+					if (level.intValue() > -1 && encloses(enclosingElement)) {
+						int offset = typeParameter.sourceStart;
+						SearchMatch match = this.patternLocator.newDeclarationMatch(typeParameter, enclosingElement, type.binding, level.intValue(), typeParameter.sourceEnd-offset+1, this);
+						report(match);
+					}
+				}
 				if (typeParameter.type != null) {
-					Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.type);
+					level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.type);
 					if (level != null && matchedClassContainer) {
-						this.patternLocator.matchReportReference(typeParameter.type, enclosingElement, level.intValue(), this);
+						this.patternLocator.matchReportReference(typeParameter.type, enclosingElement, type.binding, level.intValue(), this);
 					}
 				}
 				if (typeParameter.bounds != null) {
 					for (int j=0, b=typeParameter.bounds.length; j<b; j++) {
-						Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.bounds[j]);
+						level = (Integer) nodeSet.matchingNodes.removeKey(typeParameter.bounds[j]);
 						if (level != null && matchedClassContainer) {
-							this.patternLocator.matchReportReference(typeParameter.bounds[j], enclosingElement, level.intValue(), this);
+							this.patternLocator.matchReportReference(typeParameter.bounds[j], enclosingElement, type.binding, level.intValue(), this);
 						}
 					}
 				}
@@ -1847,7 +1987,7 @@
 			TypeReference typeRef = type.annotations[i].type;
 			Integer level = (Integer) nodeSet.matchingNodes.removeKey(typeRef);
 			if (level != null && matchedClassContainer) {
-				this.patternLocator.matchReportReference(typeRef, enclosingElement, level.intValue(), this);
+				this.patternLocator.matchReportReference(typeRef, enclosingElement, type.binding, level.intValue(), this);
 			}
 		}
 	}
@@ -1864,7 +2004,7 @@
 					ASTNode node = nodes[i];
 					Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
 					if (encloses(enclosingElement))
-						this.patternLocator.matchReportReference(node, enclosingElement, level.intValue(), this);
+						this.patternLocator.matchReportReference(node, enclosingElement, type.binding, level.intValue(), this);
 				}
 			}
 		}
@@ -1876,17 +2016,17 @@
 		if (superType != null) {
 			Integer level = (Integer) nodeSet.matchingNodes.removeKey(superType);
 			if (level != null && matchedClassContainer)
-				this.patternLocator.matchReportReference(superType, enclosingElement, level.intValue(), this);
+				this.patternLocator.matchReportReference(superType, enclosingElement, type.binding, level.intValue(), this);
 		}
 	} else {
 		TypeReference superClass = type.superclass;
 		if (superClass != null) {
-			reportMatchingSuper(superClass, enclosingElement, nodeSet, matchedClassContainer);
+			reportMatchingSuper(superClass, enclosingElement, type.binding, nodeSet, matchedClassContainer);
 		}
 		TypeReference[] superInterfaces = type.superInterfaces;
 		if (superInterfaces != null) {
 			for (int i = 0, l = superInterfaces.length; i < l; i++) {
-				reportMatchingSuper(superInterfaces[i], enclosingElement, nodeSet, matchedClassContainer);
+				reportMatchingSuper(superInterfaces[i], enclosingElement, type.binding, nodeSet, matchedClassContainer);
 			}
 		}
 	}
@@ -1928,23 +2068,11 @@
 		}
 	}
 }
-protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
+protected void reportMatchingSuper(TypeReference superReference, IJavaElement enclosingElement, Binding elementBinding, MatchingNodeSet nodeSet, boolean matchedClassContainer) throws CoreException {
 	ASTNode[] nodes = null;
-	if (superReference instanceof ParameterizedSingleTypeReference) {
-		TypeReference[] typeArguments = ((ParameterizedSingleTypeReference)superReference).typeArguments;
-		if (typeArguments != null && typeArguments.length > 0) {
-			nodes = nodeSet.matchingNodes(superReference.sourceStart, typeArguments[typeArguments.length-1].sourceEnd);
-		}
-	} else if (superReference instanceof ParameterizedQualifiedTypeReference) {
-		TypeReference[][] typeArguments = ((ParameterizedQualifiedTypeReference)superReference).typeArguments;
-		if (typeArguments != null && typeArguments.length > 0) {
-			TypeReference[] lastTypeArgs = typeArguments[typeArguments.length-1];
-			int end = superReference.sourceEnd;
-			if (lastTypeArgs != null && lastTypeArgs.length > 0 && lastTypeArgs[lastTypeArgs.length-1].sourceEnd > end) {
-				end = lastTypeArgs[lastTypeArgs.length-1].sourceEnd;
-			}
-			nodes = nodeSet.matchingNodes(superReference.sourceStart, end);
-		}
+	if (superReference instanceof ParameterizedSingleTypeReference || superReference instanceof ParameterizedQualifiedTypeReference) {
+		long lastTypeArgumentInfo = findLastTypeArgumentInfo(superReference);
+		nodes = nodeSet.matchingNodes(superReference.sourceStart, (int)lastTypeArgumentInfo);
 	}
 	if (nodes != null) {
 		if ((this.matchContainer & PatternLocator.CLASS_CONTAINER) == 0) {
@@ -1955,13 +2083,13 @@
 				for (int i = 0, l = nodes.length; i < l; i++) {
 					ASTNode node = nodes[i];
 					Integer level = (Integer) nodeSet.matchingNodes.removeKey(node);
-					this.patternLocator.matchReportReference(node, enclosingElement, level.intValue(), this);
+					this.patternLocator.matchReportReference(node, enclosingElement, elementBinding, level.intValue(), this);
 				}
 		}
 	} else {
 		Integer level = (Integer) nodeSet.matchingNodes.removeKey(superReference);
 		if (level != null && matchedClassContainer)
-			this.patternLocator.matchReportReference(superReference, enclosingElement, level.intValue(), this);
+			this.patternLocator.matchReportReference(superReference, enclosingElement, elementBinding, level.intValue(), this);
 	}
 }
 protected boolean typeInHierarchy(ReferenceBinding binding) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
index c696ec3..b0d0635 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -100,18 +100,32 @@
 public void checkComment() {
 	super.checkComment();
 	if (this.javadocParser.checkDocComment && this.javadoc != null) {
+
+		// Search for pattern locator matches in javadoc comment parameters @param tags
+		JavadocSingleNameReference[] paramReferences = this.javadoc.paramReferences;
+		int length = paramReferences == null ? 0 : paramReferences.length;
+		for (int i = 0; i < length; i++) {
+			this.patternLocator.match(paramReferences[i], this.nodeSet);
+		}
+
+		// Search for pattern locator matches in javadoc comment type parameters @param tags
+		JavadocSingleTypeReference[] paramTypeParameters = this.javadoc.paramTypeParameters;
+		length = paramTypeParameters == null ? 0 : paramTypeParameters.length;
+		for (int i = 0; i < length; i++) {
+			this.patternLocator.match(paramTypeParameters[i], this.nodeSet);
+		}
+
 		// Search for pattern locator matches in javadoc comment @throws/@exception tags
 		TypeReference[] thrownExceptions = this.javadoc.exceptionReferences;
-		int throwsTagsLength = thrownExceptions == null ? 0 : thrownExceptions.length;
-		for (int i = 0; i < throwsTagsLength; i++) {
-			TypeReference typeRef = thrownExceptions[i];
-			this.patternLocator.match(typeRef, this.nodeSet);
+		length = thrownExceptions == null ? 0 : thrownExceptions.length;
+		for (int i = 0; i < length; i++) {
+			this.patternLocator.match(thrownExceptions[i], this.nodeSet);
 		}
 
 		// Search for pattern locator matches in javadoc comment @see tags
 		Expression[] references = this.javadoc.seeReferences;
-		int seeTagsLength = references == null ? 0 : references.length;
-		for (int i = 0; i < seeTagsLength; i++) {
+		length = references == null ? 0 : references.length;
+		for (int i = 0; i < length; i++) {
 			Expression reference = references[i];
 			if (reference instanceof TypeReference) {
 				TypeReference typeRef = (TypeReference) reference;
@@ -172,6 +186,14 @@
 	super.consumeAssignment();
 	this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
 }
+protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
+	super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+}
+protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
+	super.consumeClassInstanceCreationExpressionWithTypeArguments();
+	this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
+}
 protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
 	super.consumeExplicitConstructorInvocation(flag, recFlag);
 	this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
@@ -186,6 +208,24 @@
 	// this is always a Reference
 	this.patternLocator.match((Reference) this.expressionStack[this.expressionPtr], this.nodeSet);
 }
+protected void consumeInternalCompilationUnit() {
+	// InternalCompilationUnit ::= PackageDeclaration
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports
+}
+protected void consumeInternalCompilationUnitWithTypes() {
+	// InternalCompilationUnit ::= PackageDeclaration ImportDeclarations ReduceImports TypeDeclarations
+	// InternalCompilationUnit ::= PackageDeclaration TypeDeclarations
+	// InternalCompilationUnit ::= TypeDeclarations
+	// InternalCompilationUnit ::= ImportDeclarations ReduceImports TypeDeclarations
+	// consume type declarations
+	int length;
+	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
+		this.compilationUnit.types = new TypeDeclaration[length];
+		this.astPtr -= length;
+		System.arraycopy(this.astStack, this.astPtr + 1, this.compilationUnit.types, 0, length);
+	}
+}
 protected void consumeLocalVariableDeclaration() {
 	super.consumeLocalVariableDeclaration();
 
@@ -243,6 +283,14 @@
 	intPtr--;
 	intPtr--;
 }
+protected void consumeTypeArgument() {
+	super.consumeTypeArgument();
+	patternLocator.match((TypeReference)genericsStack[genericsPtr], nodeSet);
+}
+protected void consumeTypeParameterHeader() {
+	super.consumeTypeParameterHeader();
+	patternLocator.match((TypeParameter)genericsStack[genericsPtr], nodeSet);
+}
 protected void consumeUnaryExpression(int op, boolean post) {
 	super.consumeUnaryExpression(op, post);
 	this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
@@ -352,4 +400,4 @@
 	super.consumeTypeImportOnDemandDeclarationName();
 	this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
 }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
index 7f4f4e0..fd4da6e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchingNodeSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
index 4b4bee8..2fc4632 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,6 +19,7 @@
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.core.JavaElement;
 import org.eclipse.jdt.internal.core.util.SimpleSet;
 
 public class MethodLocator extends PatternLocator {
@@ -56,32 +57,58 @@
 protected boolean isVirtualInvoke(MethodBinding method, MessageSend messageSend) {
 	return !method.isStatic() && !method.isPrivate() && !messageSend.isSuperAccess();
 }
-//public int match(ASTNode node, MatchingNodeSet nodeSet) - SKIP IT
+public int match(ASTNode node, MatchingNodeSet nodeSet) {
+	int declarationsLevel = IMPOSSIBLE_MATCH;
+	if (this.pattern.findReferences) {
+		if (node instanceof ImportReference) {
+			// With static import, we can have static method reference in import reference
+			ImportReference importRef = (ImportReference) node;
+			int length = importRef.tokens.length-1;
+			if (importRef.isStatic() && !importRef.onDemand && matchesName(this.pattern.selector, importRef.tokens[length])) {
+				char[][] compoundName = new char[length][];
+				System.arraycopy(importRef.tokens, 0, compoundName, 0, length);
+				char[] declaringType = CharOperation.concat(pattern.declaringQualification, pattern.declaringSimpleName, '.');
+				if (matchesName(declaringType, CharOperation.concatWith(compoundName, '.'))) {
+					declarationsLevel = ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+				}
+			}
+		}
+	}
+	return nodeSet.addMatch(node, declarationsLevel);
+}
 //public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
 //public int match(Expression node, MatchingNodeSet nodeSet) - SKIP IT
 //public int match(FieldDeclaration node, MatchingNodeSet nodeSet) - SKIP IT
 public int match(MethodDeclaration node, MatchingNodeSet nodeSet) {
 	if (!this.pattern.findDeclarations) return IMPOSSIBLE_MATCH;
 
+	// Verify method name
 	if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH;
+	
+	// Verify parameters types
 	if (this.pattern.parameterSimpleNames != null) {
 		int length = this.pattern.parameterSimpleNames.length;
 		ASTNode[] args = node.arguments;
 		int argsLength = args == null ? 0 : args.length;
 		if (length != argsLength) return IMPOSSIBLE_MATCH;
-
-		for (int i = 0; i < argsLength; i++)
+		for (int i = 0; i < argsLength; i++) {
 			if (!matchesTypeReference(this.pattern.parameterSimpleNames[i], ((Argument) args[i]).type)) return IMPOSSIBLE_MATCH;
+		}
 	}
-	if (!matchesTypeReference(this.pattern.returnSimpleName, node.returnType)) return IMPOSSIBLE_MATCH;
 
+	// Verify type arguments (do not reject if pattern has no argument as it can be an erasure match)
+	if (this.pattern.hasMethodArguments()) {
+		if (node.typeParameters == null || node.typeParameters.length != this.pattern.methodArguments.length) return IMPOSSIBLE_MATCH;
+	}
+
+	// Method declaration may match pattern
 	return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH);
 }
 public int match(MessageSend node, MatchingNodeSet nodeSet) {
 	if (!this.pattern.findReferences) return IMPOSSIBLE_MATCH;
 
 	if (!matchesName(this.pattern.selector, node.selector)) return IMPOSSIBLE_MATCH;
-	if (this.pattern.parameterSimpleNames != null && !this.pattern.varargs) {
+	if (this.pattern.parameterSimpleNames != null && (this.pattern.shouldCountParameter() || ((node.bits & ASTNode.InsideJavadoc) != 0))) {
 		int length = this.pattern.parameterSimpleNames.length;
 		ASTNode[] args = node.arguments;
 		int argsLength = args == null ? 0 : args.length;
@@ -96,17 +123,28 @@
 
 protected int matchContainer() {
 	if (this.pattern.findReferences) {
-		// need to look almost everywhere to find in javadocs
-		return CLASS_CONTAINER | METHOD_CONTAINER | FIELD_CONTAINER;
+		// need to look almost everywhere to find in javadocs and static import
+		return ALL_CONTAINER;
 	}
 	return CLASS_CONTAINER;
 }
+/* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchLevelAndReportImportRef(org.eclipse.jdt.internal.compiler.ast.ImportReference, org.eclipse.jdt.internal.compiler.lookup.Binding, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ * Accept to report match of static field on static import
+ */
+protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException {
+	if (importRef.isStatic() && binding instanceof MethodBinding) {
+		super.matchLevelAndReportImportRef(importRef, binding, locator);
+	}
+}
 protected int matchMethod(MethodBinding method) {
 	if (!matchesName(this.pattern.selector, method.selector)) return IMPOSSIBLE_MATCH;
 
 	int level = ACCURATE_MATCH;
 	// look at return type only if declaring type is not specified
 	if (this.pattern.declaringSimpleName == null) {
+		// TODO (frederic) use this call to refine accuracy on return type
+		// int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, this.pattern.returnTypeArguments, 0, method.returnType);
 		int newLevel = resolveLevelForType(this.pattern.returnSimpleName, this.pattern.returnQualification, method.returnType);
 		if (level > newLevel) {
 			if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
@@ -117,11 +155,15 @@
 	// parameter types
 	int parameterCount = this.pattern.parameterSimpleNames == null ? -1 : this.pattern.parameterSimpleNames.length;
 	if (parameterCount > -1) {
+		// global verification
 		if (method.parameters == null) return INACCURATE_MATCH;
 		if (parameterCount != method.parameters.length) return IMPOSSIBLE_MATCH;
-		if (!method.isValidBinding() && ((ProblemMethodBinding)method).problemId() == ProblemReasons.Ambiguous)
+		if (!method.isValidBinding() && ((ProblemMethodBinding)method).problemId() == ProblemReasons.Ambiguous) {
 			// return inaccurate match for ambiguous call (bug 80890)
 			return INACCURATE_MATCH;
+		}
+
+		// verify each parameter
 		for (int i = 0; i < parameterCount; i++) {
 			TypeBinding argType = method.parameters[i];
 			int newLevel = IMPOSSIBLE_MATCH;
@@ -131,10 +173,17 @@
 					? ACCURATE_MATCH
 					: IMPOSSIBLE_MATCH;
 			} else {
-				newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], method.parameters[i]);
+				// TODO (frederic) use this call to refine accuracy on parameter types
+//				 newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], this.pattern.parametersTypeArguments[i], 0, argType);
+				newLevel = resolveLevelForType(this.pattern.parameterSimpleNames[i], this.pattern.parameterQualifications[i], argType);
 			}
 			if (level > newLevel) {
-				if (newLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+				if (newLevel == IMPOSSIBLE_MATCH) {
+//					if (isErasureMatch) {
+//						return ERASURE_MATCH;
+//					}
+					return IMPOSSIBLE_MATCH;
+				}
 				level = newLevel; // can only be downgraded
 			}
 		}
@@ -143,9 +192,9 @@
 	return level;
 }
 /**
- * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
+ * @see org.eclipse.jdt.internal.core.search.matching.PatternLocator#matchReportReference(org.eclipse.jdt.internal.compiler.ast.ASTNode, org.eclipse.jdt.core.IJavaElement, Binding, int, org.eclipse.jdt.internal.core.search.matching.MatchLocator)
  */
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	if (this.isDeclarationOfReferencedMethodsPattern) {
 		// need exact match to be able to open on type ref
 		if (accuracy != SearchMatch.A_ACCURATE) return;
@@ -154,29 +203,102 @@
 		DeclarationOfReferencedMethodsPattern declPattern = (DeclarationOfReferencedMethodsPattern) this.pattern; 
 		while (element != null && !declPattern.enclosingElement.equals(element))
 			element = element.getParent();
-		if (element != null)
+		if (element != null) {
 			reportDeclaration(((MessageSend) reference).binding, locator, declPattern.knownMethods);
-	} else if (this.pattern.findReferences && reference instanceof MessageSend) {
-		IJavaElement focus = ((InternalSearchPattern) this.pattern).focus;
-		// verify closest match if pattern was bound
-		// (see bug 70827)
-		if (focus != null && focus.getElementType() == IJavaElement.METHOD) {
-			MethodBinding patternMethodBinding = locator.getMethodBinding((IMethod) focus);
-			if (patternMethodBinding != null && patternMethodBinding.isValidBinding()) {
+		}
+	} else {
+		match = locator.newMethodReferenceMatch(element, elementBinding, accuracy, -1, -1, false /*not constructor*/, false/*not synthetic*/, reference);
+		if (this.pattern.findReferences && reference instanceof MessageSend) {
+			IJavaElement focus = ((InternalSearchPattern) this.pattern).focus;
+			// verify closest match if pattern was bound
+			// (see bug 70827)
+			if (focus != null && focus.getElementType() == IJavaElement.METHOD) {
 				MethodBinding method = ((MessageSend)reference).binding;
-				if (method != null) {
-					method = method.original();
-					if (method != null && patternMethodBinding.isPrivate() && patternMethodBinding.declaringClass != method.declaringClass)
-						return; // finally the match was not possible
+				boolean isPrivate = Flags.isPrivate(((IMethod) focus).getFlags());
+				if (isPrivate && !CharOperation.equals(method.declaringClass.sourceName, focus.getParent().getElementName().toCharArray())) {
+					return; // finally the match was not possible
 				}
 			}
+			matchReportReference((MessageSend)reference, locator, ((MessageSend)reference).binding);
+		} else {
+			int offset = reference.sourceStart;
+			match.setOffset(offset);
+			match.setLength(reference.sourceEnd-offset+1);
+			locator.report(match);
 		}
-		int offset = (int) (((MessageSend) reference).nameSourcePosition >>> 32);
-		SearchMatch match = locator.newMethodReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, false /*not constructor*/, false/*not synthetic*/, reference);
-		locator.report(match);
+	}
+}
+void matchReportReference(MessageSend messageSend, MatchLocator locator, MethodBinding methodBinding) throws CoreException {
+
+	// Look if there's a need to special report for parameterized type
+	boolean isParameterized = false;
+	if (methodBinding instanceof ParameterizedGenericMethodBinding) { // parameterized generic method
+		isParameterized = true;
+
+		// Update match regarding method type arguments
+		ParameterizedGenericMethodBinding parameterizedMethodBinding = (ParameterizedGenericMethodBinding) methodBinding;
+		match.setRaw(parameterizedMethodBinding.isRaw);
+		TypeBinding[] typeArguments = /*parameterizedMethodBinding.isRaw ? null :*/ parameterizedMethodBinding.typeArguments;
+		updateMatch(typeArguments, locator, this.pattern.methodArguments, this.pattern.hasMethodParameters());
+
+		// Update match regarding declaring class type arguments
+		if (methodBinding.declaringClass.isParameterizedType() || methodBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)methodBinding.declaringClass;
+			if (!this.pattern.hasTypeArguments() && this.pattern.hasMethodArguments()) {
+				// special case for pattern which defines method arguments but not its declaring type
+				// in this case, we do not refine accuracy using declaring type arguments...!
+			} else {
+				updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+			}
+		} else if (this.pattern.hasTypeArguments()) {
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding method parameters
+		// TODO ? (frederic)
+
+		// Update match regarding method return type
+		// TODO ? (frederic)
+
+		// Special case for errors
+		if (match.getRule() != 0 && messageSend.resolvedType == null) {
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+	} else if (methodBinding instanceof ParameterizedMethodBinding) {
+		isParameterized = true;
+		if (methodBinding.declaringClass.isParameterizedType() || methodBinding.declaringClass.isRawType()) {
+			ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)methodBinding.declaringClass;
+			updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
+		} else if (this.pattern.hasTypeArguments()) {
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+
+		// Update match regarding method parameters
+		// TODO ? (frederic)
+
+		// Update match regarding method return type
+		// TODO ? (frederic)
+
+		// Special case for errors
+		if (match.getRule() != 0 && messageSend.resolvedType == null) {
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+		}
+	} else if (this.pattern.hasMethodArguments()) { // binding has no type params, compatible erasure if pattern does
+		match.setRule(SearchPattern.R_ERASURE_MATCH);
+	}
+
+	// See whether it is necessary to report or not
+	if (match.getRule() == 0) return; // impossible match
+	boolean report = (this.isErasureMatch && match.isErasure()) || (this.isEquivalentMatch && match.isEquivalent()) || match.isExact();
+	if (!report) return;
+
+	// Report match
+	int offset = (int) (messageSend.nameSourcePosition >>> 32);
+	match.setOffset(offset);
+	match.setLength(messageSend.sourceEnd - offset + 1);
+	 if (isParameterized && this.pattern.hasMethodArguments())  {
+		locator.reportAccurateParameterizedMethodReference(match, messageSend, messageSend.typeArguments);
 	} else {
-		int offset = reference.sourceStart;
-		SearchMatch match = locator.newMethodReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, false /*not constructor*/, false/*not synthetic*/, reference);
 		locator.report(match);
 	}
 }
@@ -205,7 +327,7 @@
 		if (resource == null)
 			resource = type.getJavaProject().getProject();
 		info = locator.getBinaryInfo((org.eclipse.jdt.internal.core.ClassFile)type.getClassFile(), resource);
-		locator.reportBinaryMemberDeclaration(resource, method, info, SearchMatch.A_ACCURATE);
+		locator.reportBinaryMemberDeclaration(resource, method, methodBinding, info, SearchMatch.A_ACCURATE);
 	} else {
 		if (declaringClass instanceof ParameterizedTypeBinding)
 			declaringClass = ((ParameterizedTypeBinding) declaringClass).type;
@@ -222,7 +344,10 @@
 			} 
 			if (methodDecl != null) {
 				int offset = methodDecl.sourceStart;
-				SearchMatch match = new MethodDeclarationMatch(method, SearchMatch.A_ACCURATE, offset, methodDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
+				Binding binding = methodDecl.binding;
+				if (binding != null)
+					method = (IMethod) ((JavaElement) method).resolved(binding);
+				match = new MethodDeclarationMatch(method, SearchMatch.A_ACCURATE, offset, methodDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
 				locator.report(match);
 			}
 		}
@@ -239,9 +364,13 @@
 	if (binding == null) return INACCURATE_MATCH;
 	if (!(binding instanceof MethodBinding)) return IMPOSSIBLE_MATCH;
 
-	MethodBinding method = ((MethodBinding) binding).original();
+	MethodBinding method = (MethodBinding) binding;
 	int methodLevel = matchMethod(method);
-	if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+	if (methodLevel == IMPOSSIBLE_MATCH) {
+		if (method != method.original()) methodLevel = matchMethod(method.original());
+		if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+		method = method.original();
+	}
 
 	// declaring type
 	char[] qualifiedPattern = qualifiedPattern(this.pattern.declaringSimpleName, this.pattern.declaringQualification);
@@ -258,11 +387,14 @@
 }
 protected int resolveLevel(MessageSend messageSend) {
 	MethodBinding method = messageSend.binding;
-	if (method != null) method = method.original();
-	if (method == null) return INACCURATE_MATCH;
+	if (method == null || messageSend.resolvedType == null) return INACCURATE_MATCH;
 	
 	int methodLevel = matchMethod(method);
-	if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+	if (methodLevel == IMPOSSIBLE_MATCH) {
+		if (method != method.original()) methodLevel = matchMethod(method.original());
+		if (methodLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
+		method = method.original();
+	}
 
 	// receiver type
 	char[] qualifiedPattern = qualifiedPattern(this.pattern.declaringSimpleName, this.pattern.declaringQualification);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
index 1696060..14497dc 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MethodPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -17,6 +17,7 @@
 import org.eclipse.jdt.core.search.SearchPattern;
 import org.eclipse.jdt.internal.core.index.*;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
 
 public class MethodPattern extends JavaSearchPattern implements IIndexConstants {
 
@@ -34,11 +35,19 @@
 public char[][] parameterQualifications;
 public char[][] parameterSimpleNames;
 public int parameterCount;
-public boolean varargs;
+public int flags = 0;
 
 // extra reference info
 protected IType declaringType;
 
+// Signatures and arguments for generic search
+char[][] returnTypeSignatures;
+char[][][] returnTypeArguments;
+char[][][] parametersTypeSignatures;
+char[][][][] parametersTypeArguments;
+boolean methodParameters = false;
+char[][] methodArguments;
+
 protected static char[][] REF_CATEGORIES = { METHOD_REF };
 protected static char[][] REF_AND_DECL_CATEGORIES = { METHOD_REF, METHOD_DECL };
 protected static char[][] DECL_CATEGORIES = { METHOD_DECL };
@@ -54,6 +63,9 @@
 	return CharOperation.concat(selector, countChars);
 }
 
+MethodPattern(int matchRule) {
+	super(METHOD_PATTERN, matchRule);
+}
 public MethodPattern(
 	boolean findDeclarations,
 	boolean findReferences,
@@ -64,7 +76,6 @@
 	char[] returnSimpleName,
 	char[][] parameterQualifications, 
 	char[][] parameterSimpleNames,
-	boolean varargs,
 	IType declaringType,
 	int matchRule) {
 
@@ -89,12 +100,146 @@
 	} else {
 		this.parameterCount = -1;
 	}
-	this.varargs = varargs;
 	this.declaringType = declaringType;
 	((InternalSearchPattern)this).mustResolve = mustResolve();
 }
-MethodPattern(int matchRule) {
-	super(METHOD_PATTERN, matchRule);
+/*
+ * Instanciate a method pattern with signatures for generics search
+ */
+public MethodPattern(
+	boolean findDeclarations,
+	boolean findReferences,
+	char[] selector, 
+	char[] declaringQualification,
+	char[] declaringSimpleName,	
+	char[] returnQualification, 
+	char[] returnSimpleName,
+	String returnSignature,
+	char[][] parameterQualifications, 
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	IMethod method,
+	int matchRule) {
+
+	this(findDeclarations,
+		findReferences,
+		selector, 
+		declaringQualification,
+		declaringSimpleName,	
+		returnQualification, 
+		returnSimpleName,
+		parameterQualifications, 
+		parameterSimpleNames,
+		method.getDeclaringType(),
+		matchRule);
+	
+	// Set flags
+	try {
+		this.flags = method.getFlags();
+	} catch (JavaModelException e) {
+		// do nothing
+	}
+
+	// Get unique key for parameterized constructors
+	String genericDeclaringTypeSignature = null;
+//	String genericSignature = null;
+	BindingKey key;
+	if (method.isResolved() && (key = new BindingKey(method.getKey())).isParameterizedType()) {
+		genericDeclaringTypeSignature = key.getDeclaringTypeSignature();
+	} else {
+		methodParameters = true;
+	}
+
+	// Store type signature and arguments for declaring type
+	if (genericDeclaringTypeSignature != null) {
+		this.typeSignatures = Util.splitTypeLevelsSignature(genericDeclaringTypeSignature);
+		setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+	} else {
+		storeTypeSignaturesAndArguments(declaringType);
+	}
+
+	// Store type signatures and arguments for return type
+	if (returnSignature != null) {
+		returnTypeSignatures = Util.splitTypeLevelsSignature(returnSignature);
+		returnTypeArguments = Util.getAllTypeArguments(returnTypeSignatures);
+	}
+
+	// Store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			parametersTypeSignatures = new char[length][][];
+			parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				parametersTypeArguments[i] = Util.getAllTypeArguments(parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	methodArguments = extractMethodArguments(method);
+	if (hasMethodArguments())  ((InternalSearchPattern)this).mustResolve = true;
+}
+/*
+ * Instanciate a method pattern with signatures for generics search
+ */
+public MethodPattern(
+	boolean findDeclarations,
+	boolean findReferences,
+	char[] selector, 
+	char[] declaringQualification,
+	char[] declaringSimpleName,	
+	String declaringSignature,
+	char[] returnQualification, 
+	char[] returnSimpleName,
+	String returnSignature,
+	char[][] parameterQualifications, 
+	char[][] parameterSimpleNames,
+	String[] parameterSignatures,
+	char[][] arguments,
+	int matchRule) {
+
+	this(findDeclarations,
+		findReferences,
+		selector, 
+		declaringQualification,
+		declaringSimpleName,	
+		returnQualification, 
+		returnSimpleName,
+		parameterQualifications, 
+		parameterSimpleNames,
+		null,
+		matchRule);
+
+	// Store type signature and arguments for declaring type
+	if (declaringSignature != null) {
+		typeSignatures = Util.splitTypeLevelsSignature(declaringSignature);
+		setTypeArguments(Util.getAllTypeArguments(typeSignatures));
+	}
+
+	// Store type signatures and arguments for return type
+	if (returnSignature != null) {
+		returnTypeSignatures = Util.splitTypeLevelsSignature(returnSignature);
+		returnTypeArguments = Util.getAllTypeArguments(returnTypeSignatures);
+	}
+
+	// Store type signatures and arguments for method parameters type
+	if (parameterSignatures != null) {
+		int length = parameterSignatures.length;
+		if (length > 0) {
+			parametersTypeSignatures = new char[length][][];
+			parametersTypeArguments = new char[length][][][];
+			for (int i=0; i<length; i++) {
+				parametersTypeSignatures[i] = Util.splitTypeLevelsSignature(parameterSignatures[i]);
+				parametersTypeArguments[i] = Util.getAllTypeArguments(parametersTypeSignatures[i]);
+			}
+		}
+	}
+
+	// Store type signatures and arguments for method
+	methodArguments = arguments;
+	if (hasMethodArguments())  ((InternalSearchPattern)this).mustResolve = true;
 }
 public void decodeIndexKey(char[] key) {
 	int size = key.length;
@@ -113,13 +258,19 @@
 		return DECL_CATEGORIES;
 	return CharOperation.NO_CHAR_CHAR;
 }
+boolean hasMethodArguments() {
+	return methodArguments != null && methodArguments.length > 0;
+}
+boolean hasMethodParameters() {
+	return methodParameters;
+}
 boolean isPolymorphicSearch() {
 	return this.findReferences;
 }
 public boolean matchesDecodedKey(SearchPattern decodedPattern) {
 	MethodPattern pattern = (MethodPattern) decodedPattern;
 
-	return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || this.varargs)
+	return (this.parameterCount == pattern.parameterCount || this.parameterCount == -1 || !shouldCountParameter())
 		&& matchesName(this.selector, pattern.selector);
 }
 /**
@@ -147,7 +298,7 @@
 
 	switch(getMatchMode()) {
 		case R_EXACT_MATCH :
-			if (!this.varargs && this.selector != null && this.parameterCount >= 0)
+			if (shouldCountParameter() && this.selector != null && this.parameterCount >= 0)
 				key = createIndexKey(this.selector, this.parameterCount);
 			else // do a prefix query with the selector
 				matchRule = matchRule - R_EXACT_MATCH + R_PREFIX_MATCH;
@@ -156,7 +307,7 @@
 			// do a prefix query with the selector
 			break;
 		case R_PATTERN_MATCH :
-			if (!this.varargs && this.parameterCount >= 0)
+			if (shouldCountParameter() && this.parameterCount >= 0)
 				key = createIndexKey(this.selector == null ? ONE_STAR : this.selector, this.parameterCount);
 			else if (this.selector != null && this.selector[this.selector.length - 1] != '*')
 				key = CharOperation.concat(this.selector, ONE_STAR, SEPARATOR);
@@ -206,4 +357,7 @@
 		output.append("*"); //$NON-NLS-1$
 	return super.print(output);
 }
+boolean shouldCountParameter() {
+	return (this.flags & Flags.AccStatic) == 0 && (this.flags & Flags.AccVarargs) == 0;
+}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
new file mode 100644
index 0000000..8573e4c
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MultiTypeDeclarationPattern.java
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import java.io.IOException;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.core.index.*;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+
+public class MultiTypeDeclarationPattern extends JavaSearchPattern implements IIndexConstants {
+
+public char[][] simpleNames;
+public char[][] qualifications;
+
+// set to CLASS_SUFFIX for only matching classes 
+// set to INTERFACE_SUFFIX for only matching interfaces
+// set to ENUM_SUFFIX for only matching enums
+// set to ANNOTATION_TYPE_SUFFIX for only matching annotation types
+// set to TYPE_SUFFIX for matching both classes and interfaces
+public char typeSuffix;
+
+protected static char[][] CATEGORIES = { TYPE_DECL };
+
+public MultiTypeDeclarationPattern(
+	char[][] qualifications,
+	char[][] simpleNames,
+	char typeSuffix,
+	int matchRule) {
+
+	this(matchRule);
+
+	if (isCaseSensitive() || qualifications == null) {
+		this.qualifications = qualifications;
+	} else {
+		int length = qualifications.length;
+		this.qualifications = new char[length][];
+		for (int i = 0; i < length; i++)
+			this.qualifications[i] = CharOperation.toLowerCase(qualifications[i]);
+	}
+	if (simpleNames == null) {
+		this.simpleNames = CharOperation.NO_CHAR_CHAR;
+	} else if (isCaseSensitive()) {
+		this.simpleNames = simpleNames;
+	} else {
+		int length = simpleNames.length;
+		this.simpleNames = new char[length][];
+		for (int i = 0; i < length; i++)
+			this.simpleNames[i] = CharOperation.toLowerCase(simpleNames[i]);
+	}
+	this.typeSuffix = typeSuffix;
+
+	((InternalSearchPattern)this).mustResolve = false; // only used to report type declarations, not their positions
+}
+MultiTypeDeclarationPattern(int matchRule) {
+	super(TYPE_DECL_PATTERN, matchRule);
+}
+public SearchPattern getBlankPattern() {
+	return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+}
+public char[][] getIndexCategories() {
+	return CATEGORIES;
+}
+public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+	QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
+	switch(this.typeSuffix) {
+		case CLASS_SUFFIX :
+		case INTERFACE_SUFFIX :
+		case ENUM_SUFFIX :
+		case ANNOTATION_TYPE_SUFFIX :
+			if (this.typeSuffix != pattern.typeSuffix) return false;
+	}
+
+	if (this.qualifications != null) {
+		int count = 0;
+		int max = this.qualifications.length;
+		for (; count < max; count++)
+			if (matchesName(this.qualifications[count], pattern.qualification))
+				break;
+		if (count == max) return false;
+	}
+
+	int count = 0;
+	int max = this.simpleNames.length;
+	for (; count < max; count++)
+		if (matchesName(this.simpleNames[count], pattern.simpleName))
+			break;
+	return count < max;
+}
+EntryResult[] queryIn(Index index) throws IOException {
+	int count = -1;
+	int numOfNames = this.simpleNames.length;
+	EntryResult[][] allResults = numOfNames > 1 ? new EntryResult[numOfNames][] : null;
+	for (int i = 0; i < numOfNames; i++) {
+		char[] key = this.simpleNames[i];
+		int matchRule = getMatchRule();
+
+		switch(getMatchMode()) {
+			case R_PREFIX_MATCH :
+				// do a prefix query with the simpleName
+				break;
+			case R_EXACT_MATCH :
+				matchRule = matchRule - R_EXACT_MATCH + R_PREFIX_MATCH;
+				key = CharOperation.append(key, SEPARATOR);
+				break; // do a prefix query with the simpleName
+			case R_PATTERN_MATCH :
+				if (key[key.length - 1] != '*')
+					key = CharOperation.concat(key, ONE_STAR, SEPARATOR);
+				break;
+		}
+
+		EntryResult[] entries = index.query(getIndexCategories(), key, matchRule); // match rule is irrelevant when the key is null
+		if (entries != null) {
+			if (allResults == null) return entries;
+			allResults[++count] = entries;
+		}
+	}
+
+	if (count == -1) return null;
+	int total = 0;
+	for (int i = 0; i <= count; i++)
+		total += allResults[i].length;
+	EntryResult[] allEntries = new EntryResult[total];
+	int next = 0;
+	for (int i = 0; i <= count; i++) {
+		EntryResult[] entries = allResults[i];
+		System.arraycopy(entries, 0, allEntries, next, entries.length);
+		next += entries.length;
+	}
+	return allEntries;
+}
+protected StringBuffer print(StringBuffer output) {
+	switch (this.typeSuffix){
+		case CLASS_SUFFIX :
+			output.append("MultiClassDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case INTERFACE_SUFFIX :
+			output.append("MultiInterfaceDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case ENUM_SUFFIX :
+			output.append("MultiEnumDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		case ANNOTATION_TYPE_SUFFIX :
+			output.append("MultiAnnotationTypeDeclarationPattern: "); //$NON-NLS-1$
+			break;
+		default :
+			output.append("MultiTypeDeclarationPattern: "); //$NON-NLS-1$
+			break;
+	}
+	if (qualifications != null) {
+		output.append("qualifications: <"); //$NON-NLS-1$
+		for (int i = 0; i < qualifications.length; i++){
+			output.append(qualifications[i]);
+			if (i < qualifications.length - 1)
+				output.append(", "); //$NON-NLS-1$
+		}
+		output.append("> "); //$NON-NLS-1$
+	}
+	if (simpleNames != null) {
+		output.append("simpleNames: <"); //$NON-NLS-1$
+		for (int i = 0; i < simpleNames.length; i++){
+			output.append(simpleNames[i]);
+			if (i < simpleNames.length - 1)
+				output.append(", "); //$NON-NLS-1$
+		}
+		output.append(">"); //$NON-NLS-1$
+	}
+	return super.print(output);
+}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
index b7b12b8..db30052 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -178,7 +178,7 @@
 	if (closestPattern != null)
 		closestPattern.matchReportImportRef(importRef, binding, element, accuracy, locator);
 }
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	PatternLocator closestPattern = null;
 	int level = IMPOSSIBLE_MATCH;
 	for (int i = 0, length = this.patternLocators.length; i < length; i++) {
@@ -191,9 +191,9 @@
 		}
 	}
 	if (closestPattern != null)
-		closestPattern.matchReportReference(reference, element, accuracy, locator);
+		closestPattern.matchReportReference(reference, element, elementBinding, accuracy, locator);
 }
-public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, int accuracy, int length, MatchLocator locator) {
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
 	PatternLocator closestPattern = null;
 	int level = IMPOSSIBLE_MATCH;
 	for (int i = 0, pl = this.patternLocators.length; i < pl; i++) {
@@ -206,10 +206,10 @@
 		}
 	}
 	if (closestPattern != null) {
-	    return closestPattern.newDeclarationMatch(reference, element, accuracy, length, locator);
+	    return closestPattern.newDeclarationMatch(reference, element, elementBinding, accuracy, length, locator);
 	}
 	// super implementation...
-    return locator.newDeclarationMatch(element, accuracy, reference.sourceStart, length);
+    return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length);
 }
 public int resolveLevel(ASTNode node) {
 	int level = IMPOSSIBLE_MATCH;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java
index 924ac36..813f3f9 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/OrPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,53 +20,88 @@
 
 public class OrPattern extends SearchPattern implements IIndexConstants {
 
-protected SearchPattern[] patterns;
+	protected SearchPattern[] patterns;
 
-public OrPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
-	super(Math.max(leftPattern.getMatchRule(), rightPattern.getMatchRule()));
-	((InternalSearchPattern)this).kind = OR_PATTERN;
-	((InternalSearchPattern)this).mustResolve = ((InternalSearchPattern) leftPattern).mustResolve || ((InternalSearchPattern) rightPattern).mustResolve;
+	/*
+	 * Whether this pattern is erasure match.
+	 */
+//	boolean isErasureMatch;
 
-	SearchPattern[] leftPatterns = leftPattern instanceof OrPattern ? ((OrPattern) leftPattern).patterns : null;
-	SearchPattern[] rightPatterns = rightPattern instanceof OrPattern ? ((OrPattern) rightPattern).patterns : null;
-	int leftSize = leftPatterns == null ? 1 : leftPatterns.length;
-	int rightSize = rightPatterns == null ? 1 : rightPatterns.length;
-	this.patterns = new SearchPattern[leftSize + rightSize];
+	/**
+	 * One of {@link #R_ERASURE_MATCH}, {@link #R_EQUIVALENT_MATCH}, {@link #R_FULL_MATCH}.
+	 */
+	int matchCompatibility;
 
-	if (leftPatterns == null)
-		this.patterns[0] = leftPattern;
-	else
-		System.arraycopy(leftPatterns, 0, this.patterns, 0, leftSize);
-	if (rightPatterns == null)
-		this.patterns[leftSize] = rightPattern;
-	else
-		System.arraycopy(rightPatterns, 0, this.patterns, leftSize, rightSize);
-}
-void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) throws IOException {
-	// per construction, OR pattern can only be used with a PathCollector (which already gather results using a set)
-	try {
-		index.startQuery();
+	public OrPattern(SearchPattern leftPattern, SearchPattern rightPattern) {
+		super(Math.max(leftPattern.getMatchRule(), rightPattern.getMatchRule()));
+		((InternalSearchPattern)this).kind = OR_PATTERN;
+		((InternalSearchPattern)this).mustResolve = ((InternalSearchPattern) leftPattern).mustResolve || ((InternalSearchPattern) rightPattern).mustResolve;
+	
+		SearchPattern[] leftPatterns = leftPattern instanceof OrPattern ? ((OrPattern) leftPattern).patterns : null;
+		SearchPattern[] rightPatterns = rightPattern instanceof OrPattern ? ((OrPattern) rightPattern).patterns : null;
+		int leftSize = leftPatterns == null ? 1 : leftPatterns.length;
+		int rightSize = rightPatterns == null ? 1 : rightPatterns.length;
+		this.patterns = new SearchPattern[leftSize + rightSize];
+	
+		if (leftPatterns == null)
+			this.patterns[0] = leftPattern;
+		else
+			System.arraycopy(leftPatterns, 0, this.patterns, 0, leftSize);
+		if (rightPatterns == null)
+			this.patterns[leftSize] = rightPattern;
+		else
+			System.arraycopy(rightPatterns, 0, this.patterns, leftSize, rightSize);
+
+		// Store erasure match
+		matchCompatibility = 0;
+		for (int i = 0, length = this.patterns.length; i < length; i++) {
+			matchCompatibility |= ((JavaSearchPattern) this.patterns[i]).matchCompatibility;
+		}
+	}
+	void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) throws IOException {
+		// per construction, OR pattern can only be used with a PathCollector (which already gather results using a set)
+		try {
+			index.startQuery();
+			for (int i = 0, length = this.patterns.length; i < length; i++)
+				((InternalSearchPattern)this.patterns[i]).findIndexMatches(index, requestor, participant, scope, progressMonitor);
+		} finally {
+			index.stopQuery();
+		}
+	}
+
+	public SearchPattern getBlankPattern() {
+		return null;
+	}
+
+	boolean isErasureMatch() {
+		return (this.matchCompatibility & R_ERASURE_MATCH) != 0;
+	}
+
+	boolean isPolymorphicSearch() {
 		for (int i = 0, length = this.patterns.length; i < length; i++)
-			((InternalSearchPattern)this.patterns[i]).findIndexMatches(index, requestor, participant, scope, progressMonitor);
-	} finally {
-		index.stopQuery();
+			if (((InternalSearchPattern) this.patterns[i]).isPolymorphicSearch()) return true;
+		return false;
 	}
-}
-public SearchPattern getBlankPattern() {
-	return null;
-}
-boolean isPolymorphicSearch() {
-	for (int i = 0, length = this.patterns.length; i < length; i++)
-		if (((InternalSearchPattern) this.patterns[i]).isPolymorphicSearch()) return true;
-	return false;
-}
-public String toString() {
-	StringBuffer buffer = new StringBuffer();
-	buffer.append(this.patterns[0].toString());
-	for (int i = 1, length = this.patterns.length; i < length; i++) {
-		buffer.append("\n| "); //$NON-NLS-1$
-		buffer.append(this.patterns[i].toString());
+
+	/**
+	 * Returns whether the pattern has signatures or not.
+	 * @return true if one at least of the stored pattern has signatures.
+	 */
+	public final boolean hasSignatures() {
+		boolean isErasureMatch = isErasureMatch();
+		for (int i = 0, length = this.patterns.length; i < length && !isErasureMatch; i++) {
+			if (((JavaSearchPattern) this.patterns[i]).hasSignatures()) return true;
+		}
+		return false;
 	}
-	return buffer.toString();
-}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(this.patterns[0].toString());
+		for (int i = 1, length = this.patterns.length; i < length; i++) {
+			buffer.append("\n| "); //$NON-NLS-1$
+			buffer.append(this.patterns[i].toString());
+		}
+		return buffer.toString();
+	}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java
index 4172f22..e9f1ce1 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java
index 4275a38..2878c9a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageDeclarationPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
index 0001f5a..8d5ef8a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferenceLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,7 +16,6 @@
 import org.eclipse.jdt.core.IPackageFragment;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.search.SearchMatch;
 import org.eclipse.jdt.core.search.SearchPattern;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.*;
@@ -130,6 +129,10 @@
 			FieldBinding fieldBinding = (FieldBinding) binding;
 			if (!fieldBinding.isStatic()) return;
 			refBinding = fieldBinding.declaringClass;
+		} else if (binding instanceof MethodBinding) {
+			MethodBinding methodBinding = (MethodBinding) binding;
+			if (!methodBinding.isStatic()) return;
+			refBinding = methodBinding.declaringClass;
 		} else if (binding instanceof MemberTypeBinding) {
 			MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
 			if (!memberBinding.isStatic()) return;
@@ -139,7 +142,7 @@
 }
 protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
 	if (binding == null) {
-		this.matchReportReference(importRef, element, accuracy, locator);
+		this.matchReportReference(importRef, element, null/*no binding*/, accuracy, locator);
 	} else {
 		if (locator.encloses(element)) {
 			long[] positions = importRef.sourcePositions;
@@ -155,12 +158,12 @@
 				last = ((PackageBinding) binding).compoundName.length;
 			int start = (int) (positions[0] >>> 32);
 			int end = (int) positions[last - 1];
-			SearchMatch match = locator.newPackageReferenceMatch(element, accuracy, start, end-start+1, importRef);
+			match = locator.newPackageReferenceMatch(element, accuracy, start, end-start+1, importRef);
 			locator.report(match);
 		}
 	}
 }
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	long[] positions = null;
 	int last = -1;
 	if (reference instanceof ImportReference) {
@@ -222,7 +225,7 @@
 	if (last > positions.length) last = positions.length;
 	int sourceStart = (int) (positions[0] >>> 32);
 	int sourceEnd = ((int) positions[last - 1]);
-	SearchMatch match = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference);
+	match = locator.newPackageReferenceMatch(element, accuracy, sourceStart, sourceEnd-sourceStart+1, reference);
 	locator.report(match);
 }
 protected int referenceType() {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java
index 01f8615..623b5b3 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PackageReferencePattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
index 8b0cc69..0513a84 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PatternLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -27,6 +27,9 @@
 protected boolean isErasureMatch;
 protected boolean mustResolve;
 
+// match to report
+SearchMatch match = null;
+
 /* match levels */
 public static final int IMPOSSIBLE_MATCH = 0;
 public static final int INACCURATE_MATCH = 1;
@@ -68,6 +71,8 @@
 			return new OrLocator((OrPattern) pattern);
 		case IIndexConstants.LOCAL_VAR_PATTERN :
 			return new LocalVariableLocator((LocalVariablePattern) pattern);
+		case IIndexConstants.TYPE_PARAM_PATTERN:
+			return new TypeParameterLocator((TypeParameterPattern) pattern);
 	}
 	return null;
 }
@@ -187,6 +192,10 @@
 	// each subtype should override if needed
 	return IMPOSSIBLE_MATCH;
 }
+public int match(TypeParameter node, MatchingNodeSet nodeSet) {
+	// each subtype should override if needed
+	return IMPOSSIBLE_MATCH;
+}
 public int match(TypeReference node, MatchingNodeSet nodeSet) {
 	// each subtype should override if needed
 	return IMPOSSIBLE_MATCH;
@@ -270,14 +279,14 @@
 protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
 	if (locator.encloses(element)) {
 		// default is to report a match as a regular ref.
-		this.matchReportReference(importRef, element, accuracy, locator);
+		this.matchReportReference(importRef, element, null/*no binding*/, accuracy, locator);
 	}
 }
 /**
  * Reports the match of the given reference.
  */
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
-	SearchMatch match = null;
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
+	match = null;
 	int referenceType = referenceType();
 	int offset = reference.sourceStart;
 	switch (referenceType) {
@@ -285,26 +294,24 @@
 			match = locator.newPackageReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
 			break;
 		case IJavaElement.TYPE:
-			match = locator.newTypeReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference);
 			break;
 		case IJavaElement.FIELD:
-			match = locator.newFieldReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
-			break;
-		case IJavaElement.METHOD:
-			boolean isConstructor = reference instanceof ExplicitConstructorCall;
-			boolean isSynthetic = isConstructor ? ((ExplicitConstructorCall) reference).isImplicitSuper() : false;
-			match = locator.newMethodReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, isConstructor, isSynthetic, reference);
+			match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference);
 			break;
 		case IJavaElement.LOCAL_VARIABLE:
 			match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
 			break;
+		case IJavaElement.TYPE_PARAMETER:
+			match = locator.newTypeParameterReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
+			break;
 	}
 	if (match != null) {
 		locator.report(match);
 	}
 }
-public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, int accuracy, int length, MatchLocator locator) {
-    return locator.newDeclarationMatch(element, accuracy, reference.sourceStart, length);
+public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) {
+    return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length);
 }
 protected int referenceType() {
 	return 0; // defaults to unknown (a generic JavaSearchMatch will be created)
@@ -323,63 +330,98 @@
 	return IMPOSSIBLE_MATCH;
 }
 /*
- * Refine accuracy for a match.
- * Typically this happens while search references to parameterized type.
- * In this case we need locator to be able to resolve type arguments and verify
- * if binding is compatible with pattern...
- * Look also for enclosing type
+ * Update pattern locator match for parameterized top level types.
+ * Set match raw flag and recurse to enclosing types if any...
  */
-protected int refineAccuracy(int accuracy, ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) {
-	// We can only refine if locator has an unit scope.
-	if (locator.unitScope == null) return accuracy;
-	return refineAccuracy(accuracy, parameterizedBinding, patternTypeArguments, false, 0, locator);
+protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) {
+	// Only possible if locator has an unit scope.
+	if (locator.unitScope != null) {
+		updateMatch(parameterizedBinding, patternTypeArguments, false, 0, locator);
+	}
 }
-int refineAccuracy(int accuracy, ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, boolean isPatternSourceType, int depth, MatchLocator locator) {
+/*
+ * Update pattern locator match for parameterized top or sub level types.
+ * Set match raw flag and recurse to enclosing types if any...
+ */
+protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, boolean patternHasTypeParameters, int depth, MatchLocator locator) {
+	// Only possible if locator has an unit scope.
+	if (locator.unitScope == null) return;
+
+	// Set match raw flag
+	boolean endPattern = patternTypeArguments==null  ? true  : depth>=patternTypeArguments.length;
+	char[][] patternArguments =  endPattern ? null : patternTypeArguments[depth];
+	boolean isRaw = parameterizedBinding.isRawType()|| (parameterizedBinding.arguments==null && parameterizedBinding.type.isGenericType());
+	if (isRaw && !match.isRaw()) {
+		match.setRaw(isRaw);
+	}
+	
+	// Update match
+	if (!endPattern) {
+		updateMatch(parameterizedBinding.arguments, locator, patternArguments, patternHasTypeParameters);
+	}
+
+	// Recurse
+	TypeBinding enclosingType = parameterizedBinding.enclosingType();
+	if (enclosingType != null && (enclosingType.isParameterizedType() || enclosingType.isRawType())) {
+		updateMatch((ParameterizedTypeBinding)enclosingType, patternTypeArguments, patternHasTypeParameters, depth+1, locator);
+	}
+}
+/*
+ * Update pattern locator match comparing type arguments with pattern ones.
+ * Try to resolve pattern and look for compatibility with type arguments
+ * to set match rule.
+ */
+protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments, boolean hasTypeParameters) {
+	// Only possible if locator has an unit scope.
+	if (locator.unitScope == null) return;
 
 	// First compare lengthes
-	int patternTypeArgsLength = (patternTypeArguments==null || depth>=patternTypeArguments.length || patternTypeArguments[depth] == null) ? 0 : patternTypeArguments[depth].length;
-	TypeBinding[] argumentsBinding = parameterizedBinding.arguments;
+	int patternTypeArgsLength = patternArguments==null ? 0 : patternArguments.length;
 	int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length;
-	int refinedAccuracy =  accuracy;
+
+	// Initialize match rule
+	int matchRule = match.getRule();
+	if (match.isRaw()) {
+		if (patternTypeArgsLength != 0) {
+			matchRule &= ~SearchPattern.R_FULL_MATCH;
+		}
+	}
+	if (hasTypeParameters) {
+		matchRule = SearchPattern.R_ERASURE_MATCH;
+	}
+	
+	// Compare arguments lengthes
 	if (patternTypeArgsLength == typeArgumentsLength) {
-		if (patternTypeArgsLength == 0) {
-			if (isPatternSourceType) { // raw source type pattern is always compatible erasure...
-				if (refinedAccuracy <= SearchMatch.A_INACCURATE) // ...except if accuracy has been already refined
-					refinedAccuracy |= RAW_MASK;
-			}
-		} else {
-			if (isPatternSourceType) {
-				// parameterized source type pattern is always an incompatible erasure match
-				refinedAccuracy |= SearchPattern.R_ERASURE_MATCH;
-				refinedAccuracy &= ~SearchPattern.R_EQUIVALENT_MATCH;
-			}
+		if (!match.isRaw() && hasTypeParameters) {
+			// generic patterns are always not compatible match
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+			return;
 		}
 	} else {
-		if (patternTypeArgsLength==0) { // raw pattern
-			if (patternTypeArguments == null || depth < patternTypeArguments.length) {
-				// if valid type arguments, then it is always compatible erasure except if accuracy has been already refined
-				if (refinedAccuracy <= SearchMatch.A_INACCURATE)
-					refinedAccuracy |= RAW_MASK;
+		if (patternTypeArgsLength==0) {
+			if (!match.isRaw() || hasTypeParameters) {
+				match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
 			}
-			return refinedAccuracy;
-		} else  if (typeArgumentsLength==0) { // raw binding
-			// then it is always compatible erasure except if accuracy has been already refined
-			if (refinedAccuracy <= SearchMatch.A_INACCURATE)
-				refinedAccuracy |= RAW_MASK;
-			return refinedAccuracy;
+		} else  if (typeArgumentsLength==0) {
+			// raw binding is always compatible
+			match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH);
+		} else {
+			match.setRule(0); // impossible match
 		}
-		return -1;
+		return;
 	}
 
 	// Compare binding for each type argument only if pattern is not erasure only and at first level
-//	int refinedAccuracy = SearchMatch.A_ACCURATE;
-	if (!isPatternSourceType) {
+	if (!hasTypeParameters && !match.isRaw() && (match.isEquivalent() || match.isExact())) {
 		for (int i=0; i<typeArgumentsLength; i++) {
 			// Get parameterized type argument binding
 			TypeBinding argumentBinding = argumentsBinding[i];
-
+			if (argumentBinding instanceof CaptureBinding) {
+				WildcardBinding capturedWildcard = ((CaptureBinding)argumentBinding).wildcard;
+				if (capturedWildcard != null) argumentBinding = capturedWildcard;
+			}
 			// Get binding for pattern argument
-			char[] patternTypeArgument = patternTypeArguments[depth][i];
+			char[] patternTypeArgument = patternArguments[i];
 			char patternWildcard = patternTypeArgument[0];
 			char[] patternTypeName = patternTypeArgument;
 			int patternWildcardKind = -1;
@@ -387,9 +429,9 @@
 				case Signature.C_STAR:
 					if (argumentBinding.isWildcard()) {
 						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
-						if (wildcardBinding.kind == Wildcard.UNBOUND) continue;
+						if (wildcardBinding.boundKind == Wildcard.UNBOUND) continue;
 					}
-					if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+					matchRule &= ~SearchPattern.R_FULL_MATCH;
 					continue; // unbound parameter always match
 				case Signature.C_EXTENDS :
 					patternWildcardKind = Wildcard.EXTENDS;
@@ -408,10 +450,11 @@
 			if (patternBinding == null) {
 				if (argumentBinding.isWildcard()) {
 					WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
-					if (wildcardBinding.kind == Wildcard.UNBOUND) {
-						if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+					if (wildcardBinding.boundKind == Wildcard.UNBOUND) {
+						matchRule &= ~SearchPattern.R_FULL_MATCH;
 					} else {
-						refinedAccuracy |= SearchPattern.R_ERASURE_MATCH;
+						match.setRule(SearchPattern.R_ERASURE_MATCH);
+						return;
 					}
 				}
 				continue;
@@ -421,33 +464,33 @@
 			switch (patternWildcard) {
 				case Signature.C_STAR : // UNBOUND pattern
 					// unbound always match => skip to next argument
-					if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+					matchRule &= ~SearchPattern.R_FULL_MATCH;
 					continue;
 				case Signature.C_EXTENDS : // EXTENDS pattern
 					if (argumentBinding.isWildcard()) { // argument is a wildcard
 						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
 						// It's ok if wildcards are identical
-						if (wildcardBinding.kind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
+						if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
 							continue;
 						}
 						// Look for wildcard compatibility
-						switch (wildcardBinding.kind) {
+						switch (wildcardBinding.boundKind) {
 							case Wildcard.EXTENDS:
 								if (wildcardBinding.bound== null || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
 									// valid when arg extends a subclass of pattern
-									if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
 									continue;
 								}
 								break;
 							case Wildcard.SUPER:
 								break;
 							case Wildcard.UNBOUND:
-								if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+								matchRule &= ~SearchPattern.R_FULL_MATCH;
 								continue;
 						}
 					} else if (argumentBinding.isCompatibleWith(patternBinding)) {
 						// valid when arg is a subclass of pattern 
-						if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+						matchRule &= ~SearchPattern.R_FULL_MATCH;
 						continue;
 					}
 					break;
@@ -455,50 +498,50 @@
 					if (argumentBinding.isWildcard()) { // argument is a wildcard
 						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
 						// It's ok if wildcards are identical
-						if (wildcardBinding.kind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
+						if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) {
 							continue;
 						}
 						// Look for wildcard compatibility
-						switch (wildcardBinding.kind) {
+						switch (wildcardBinding.boundKind) {
 							case Wildcard.EXTENDS:
 								break;
 							case Wildcard.SUPER:
 								if (wildcardBinding.bound== null || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
 									// valid only when arg super a superclass of pattern
-									if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
 									continue;
 								}
 								break;
 							case Wildcard.UNBOUND:
-								if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+								matchRule &= ~SearchPattern.R_FULL_MATCH;
 								continue;
 						}
 					} else if (patternBinding.isCompatibleWith(argumentBinding)) {
 						// valid only when arg is a superclass of pattern
-						if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+						matchRule &= ~SearchPattern.R_FULL_MATCH;
 						continue;
 					}
 					break;
 				default:
 					if (argumentBinding.isWildcard()) {
 						WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding;
-						switch (wildcardBinding.kind) {
+						switch (wildcardBinding.boundKind) {
 							case Wildcard.EXTENDS:
 								if (wildcardBinding.bound== null || patternBinding.isCompatibleWith(wildcardBinding.bound)) {
 									// valid only when arg extends a superclass of pattern
-									if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
 									continue;
 								}
 								break;
 							case Wildcard.SUPER:
 								if (wildcardBinding.bound== null || wildcardBinding.bound.isCompatibleWith(patternBinding)) {
 									// valid only when arg super a subclass of pattern
-									if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+									matchRule &= ~SearchPattern.R_FULL_MATCH;
 									continue;
 								}
 								break;
 							case Wildcard.UNBOUND:
-								if (refinedAccuracy < SearchPattern.R_ERASURE_MATCH) refinedAccuracy |= SearchPattern.R_EQUIVALENT_MATCH;
+								matchRule &= ~SearchPattern.R_FULL_MATCH;
 								continue;
 						}
 					} else if (argumentBinding == patternBinding)
@@ -508,18 +551,13 @@
 			}
 			
 			// Argument does not match => erasure match will be the only possible one
-			return SearchPattern.R_ERASURE_MATCH;
+			match.setRule(SearchPattern.R_ERASURE_MATCH);
+			return;
 		}
 	}
 
-	// Recurse refining on enclosing types if any
-	TypeBinding enclosingType = parameterizedBinding.enclosingType();
-	if (enclosingType != null && (enclosingType.isParameterizedType() || enclosingType.isRawType())) {
-		return refineAccuracy(refinedAccuracy, (ParameterizedTypeBinding)enclosingType, patternTypeArguments, isPatternSourceType, depth+1, locator);
-	}
-	
-	// Refine the accuracy to accurate
-	return refinedAccuracy;
+	// Set match rule
+	match.setRule(matchRule);
 }
 /**
  * Finds out whether the given binding matches this search pattern.
@@ -546,18 +584,18 @@
 	char[] qualifiedPattern = getQualifiedPattern(simpleNamePattern, qualificationPattern);
 	int level = resolveLevelForType(qualifiedPattern, binding);
 	if (level == ACCURATE_MATCH || binding == null) return level;
-	boolean match = false;
+	boolean matchPattern = false;
 	TypeBinding type = binding instanceof ArrayBinding ? ((ArrayBinding)binding).leafComponentType : binding;
 	if (type.isMemberType() || type.isLocalType()) {
 		if (qualificationPattern != null) {
-			match = CharOperation.match(qualifiedPattern, getQualifiedSourceName(binding), this.isCaseSensitive);
+			matchPattern = CharOperation.match(qualifiedPattern, getQualifiedSourceName(binding), this.isCaseSensitive);
 		} else {
-			match = CharOperation.match(qualifiedPattern, binding.sourceName(), this.isCaseSensitive); // need to keep binding to get source name
+			matchPattern = CharOperation.match(qualifiedPattern, binding.sourceName(), this.isCaseSensitive); // need to keep binding to get source name
 		}
 	} else if (qualificationPattern == null) {
-		match = CharOperation.match(qualifiedPattern, getQualifiedSourceName(binding), this.isCaseSensitive);
+		matchPattern = CharOperation.match(qualifiedPattern, getQualifiedSourceName(binding), this.isCaseSensitive);
 	}
-	return match ? ACCURATE_MATCH : IMPOSSIBLE_MATCH;
+	return matchPattern ? ACCURATE_MATCH : IMPOSSIBLE_MATCH;
 
 }
 
@@ -596,7 +634,9 @@
 	// standard search with no generic additional information must succeed
 	int level = resolveLevelForType(simpleNamePattern, qualificationPattern, type);
 	if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH;
-	if (type == null || patternTypeArguments == null|| patternTypeArguments.length == 0 || depth>=patternTypeArguments.length || patternTypeArguments[depth] == null) return level;
+	if (type == null || patternTypeArguments == null || patternTypeArguments.length == 0 || depth >= patternTypeArguments.length) {
+		return level;
+	}
 	
 	// if pattern is erasure match (see bug 79790), commute impossible to erasure
 	int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH;
@@ -614,12 +654,10 @@
 			if (this.mustResolve)
 				typeVariables = binaryTypeBinding.typeVariables(); // TODO (frederic) verify performance
 		}
-		// type variables length must match at least specified type names length
-		if (typeVariables == null || typeVariables.length == 0) {
-			return IMPOSSIBLE_MATCH;
+		if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
+			typeVariables != null && typeVariables.length > 0) {
+			if (typeVariables.length != patternTypeArguments[depth].length) return IMPOSSIBLE_MATCH;
 		}
-		int length = patternTypeArguments[depth].length;
-		if (typeVariables.length != length) return IMPOSSIBLE_MATCH;
 		// TODO (frederic) do we need to verify each parameter?
 		return level; // we can't do better
 	} else if (isRawType) {
@@ -627,11 +665,13 @@
 	} else if (!type.isParameterizedType()) {
 		// Standard types (ie. neither generic nor parameterized nor raw types)
 		// cannot match pattern with type parameters or arguments
-		return IMPOSSIBLE_MATCH;
+		return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH;
 	} else {
 		ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) type;
-		// When there's no type argument, no verification is necessary 
-		if (paramTypeBinding.arguments != null) {
+
+		// Compare arguments only if there ones on both sides
+		if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 &&
+			paramTypeBinding.arguments != null && paramTypeBinding.arguments.length > 0) {
 
 			// type parameters length must match at least specified type names length
 			int length = patternTypeArguments[depth].length;
@@ -661,9 +701,13 @@
 	
 				// Verify that names match...
 				// ...special case for wildcard
+				if (argTypeBinding instanceof CaptureBinding) {
+					WildcardBinding capturedWildcard = ((CaptureBinding)argTypeBinding).wildcard;
+					if (capturedWildcard != null) argTypeBinding = capturedWildcard;
+				}
 				if (argTypeBinding.isWildcard()) {
 					WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding;
-					switch (wildcardBinding.kind) {
+					switch (wildcardBinding.boundKind) {
 						case Wildcard.EXTENDS:
 							// Invalid if type argument is not exact
 							if (patternTypeArgHasAnyChars) return impossible;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
index ba0eea2..1b2021e 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -98,7 +98,7 @@
 		// get file name
 		String fileName = this.resource.getFullPath().lastSegment();
 		// get main type name
-		char[] mainTypeName = fileName.substring(0, fileName.length()-5).toCharArray(); 
+		char[] mainTypeName = Util.getNameWithoutJavaLikeExtension(fileName).toCharArray();
 		CompilationUnit cu = (CompilationUnit) this.openable;
 		return cu.getType(new String(mainTypeName)).getFullyQualifiedName().toCharArray();
 	} else if (this.openable instanceof ClassFile) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java
index f50e658..efb86cb 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatchSet.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
index 0166611..1c0d908 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/QualifiedTypeDeclarationPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -16,7 +16,8 @@
 
 public class QualifiedTypeDeclarationPattern extends TypeDeclarationPattern implements IIndexConstants {
 
-protected char[] qualification;
+public char[] qualification;
+public int packageIndex;
 
 public QualifiedTypeDeclarationPattern(char[] qualification, char[] simpleName, char typeSuffix, int matchRule) {
 	this(matchRule);
@@ -37,20 +38,39 @@
 	int start = slash + 1;
 	slash = CharOperation.indexOf(SEPARATOR, key, start);
 	int secondSlash = CharOperation.indexOf(SEPARATOR, key, slash + 1);
+	this.packageIndex = -1; // used to compute package vs. enclosingTypeNames in MultiTypeDeclarationPattern
 	if (start + 1 == secondSlash) {
 		this.qualification = CharOperation.NO_CHAR; // no package name or enclosingTypeNames
 	} else if (slash + 1 == secondSlash) {
 		this.qualification = CharOperation.subarray(key, start, slash); // only a package name
+	} else if (slash == start) {
+		this.qualification = CharOperation.subarray(key, slash + 1, secondSlash); // no package name
+		this.packageIndex = 0;
 	} else {
 		this.qualification = CharOperation.subarray(key, start, secondSlash);
-		this.qualification[slash - start] = '.';
+		this.packageIndex = slash - start;
+		this.qualification[this.packageIndex] = '.';
 	}
 
-	this.typeSuffix = key[key.length - 1];
+	decodeModifiers(key[key.length - 1]);
 }
 public SearchPattern getBlankPattern() {
 	return new QualifiedTypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
 }
+public char[] getPackageName() {
+	if (this.packageIndex == -1)
+		return this.qualification;
+	return CharOperation.subarray(this.qualification, 0, this.packageIndex);
+}
+public char[][] getEnclosingTypeNames() {
+	if (this.packageIndex == -1)
+		return CharOperation.NO_CHAR_CHAR;
+	if (this.packageIndex == 0)
+		return CharOperation.splitOn('.', this.qualification);
+
+	char[] names = CharOperation.subarray(this.qualification, this.packageIndex + 1, this.qualification.length);
+	return CharOperation.splitOn('.', names);
+}
 public boolean matchesDecodedKey(SearchPattern decodedPattern) {
 	QualifiedTypeDeclarationPattern pattern = (QualifiedTypeDeclarationPattern) decodedPattern;
 	switch(this.typeSuffix) {
@@ -90,6 +110,7 @@
 		output.append(simpleName);
 	else
 		output.append("*"); //$NON-NLS-1$
+	output.append("> "); //$NON-NLS-1$
 	return super.print(output);
 }
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java
index dacb9f1..06d33b4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeNamesCollector.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -20,7 +20,7 @@
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.ast.*;
-import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 import org.eclipse.jdt.internal.core.*;
@@ -113,7 +113,7 @@
 protected CompilationUnitDeclaration buildBindings(ICompilationUnit compilationUnit, boolean isTopLevelOrMember) throws JavaModelException {
 	final IFile file = (IFile) compilationUnit.getResource();
 	final String fileName = file.getFullPath().lastSegment();
-	final char[] mainTypeName = fileName.substring(0, fileName.length() - 5).toCharArray();
+	final char[] mainTypeName = Util.getNameWithoutJavaLikeExtension(fileName).toCharArray();
 
 	// source unit
 	IBuffer buffer = compilationUnit.getBuffer();
@@ -250,7 +250,7 @@
 		IIndexConstants.TYPE_SUFFIX,
 		this.pattern.getMatchRule());
 	IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
-		public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRestriction access) {
+		public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
 			TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
 			if (record.enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR) {  // filter out local and anonymous classes
 				pathCollector.acceptIndexMatch(documentPath, indexRecord, participant, access);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java
index 3f8b2dd..c01a429 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferenceLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java
index 1fab6c9..0710b98 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/SuperTypeReferencePattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
index e84e5a5..1a52791 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
index cac2eeb..0ceee8a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeDeclarationPattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,6 +14,7 @@
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.SearchPattern;
+import org.eclipse.jdt.internal.compiler.env.IConstants;
 import org.eclipse.jdt.internal.core.index.*;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
 
@@ -29,10 +30,15 @@
 // set to ANNOTATION_TYPE_SUFFIX for only matching annotation types
 // set to TYPE_SUFFIX for matching both classes and interfaces
 public char typeSuffix; 
+public int modifiers;
 
 protected static char[][] CATEGORIES = { TYPE_DECL };
 
-public static char[] createIndexKey(char[] typeName, char[] packageName, char[][] enclosingTypeNames, char typeSuffix) {
+/*
+ * Create index key for type declaration pattern:
+ *		key = typeName / packageName / enclosingTypeName / typeSuffix modifiers
+ */
+public static char[] createIndexKey(int modifiers, char[] typeName, char[] packageName, char[][] enclosingTypeNames) { //, char typeSuffix) {
 	int typeNameLength = typeName == null ? 0 : typeName.length;
 	int packageLength = packageName == null ? 0 : packageName.length;
 	int enclosingNamesLength = 0;
@@ -67,7 +73,7 @@
 		}
 	}
 	result[pos++] = SEPARATOR;
-	result[pos] = typeSuffix;
+	result[pos] = (char) modifiers;
 	return result;
 }
 
@@ -98,10 +104,10 @@
 	super(TYPE_DECL_PATTERN, matchRule);
 }
 /*
- * Type entries are encoded as simpleTypeName / packageName / enclosingTypeName / 'C' or 'I'
- * e.g. Object/java.lang//C
- * e.g. Cloneable/java.lang//I
- * e.g. LazyValue/javax.swing/UIDefaults/C
+ * Type entries are encoded as simpleTypeName / packageName / enclosingTypeName / modifiers
+ * e.g. Object/java.lang//0
+ * e.g. Cloneable/java.lang//512
+ * e.g. LazyValue/javax.swing/UIDefaults/0
  */
 public void decodeIndexKey(char[] key) {
 	int slash = CharOperation.indexOf(SEPARATOR, key, 0);
@@ -119,7 +125,28 @@
 		this.enclosingTypeNames = CharOperation.equals(ONE_ZERO, names) ? ONE_ZERO_CHAR : CharOperation.splitOn('.', names);
 	}
 
-	this.typeSuffix = key[key.length - 1];
+	decodeModifiers(key[key.length - 1]);
+}
+protected void decodeModifiers(char value) {
+	this.modifiers = value; // implicit cast to int type
+
+	// Extract suffix from modifiers instead of index key
+	int kind = this.modifiers & (IConstants.AccInterface+IConstants.AccEnum+IConstants.AccAnnotation);
+	switch (kind) {
+		case IConstants.AccAnnotation:
+		case IConstants.AccAnnotation+IConstants.AccInterface:
+			this.typeSuffix = ANNOTATION_TYPE_SUFFIX;
+			break;
+		case IConstants.AccEnum:
+			this.typeSuffix = ENUM_SUFFIX;
+			break;
+		case IConstants.AccInterface:
+			this.typeSuffix = INTERFACE_SUFFIX;
+			break;
+		default:
+			this.typeSuffix = CLASS_SUFFIX;
+			break;
+	}
 }
 public SearchPattern getBlankPattern() {
 	return new TypeDeclarationPattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterLocator.java
new file mode 100644
index 0000000..2eb85b8
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterLocator.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.compiler.ast.*;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
+
+/**
+ * Search engine locator for type parameters matches.
+ */
+public class TypeParameterLocator extends PatternLocator {
+
+	protected TypeParameterPattern pattern;
+
+	public TypeParameterLocator(TypeParameterPattern pattern) {
+		super(pattern);
+		this.pattern = pattern;
+	}
+
+	/*
+	 * Verify whether a type reference matches name pattern.
+	 * Type parameter references (ie. type arguments) are compiler type reference nodes
+	 */
+	public int match(TypeReference node, MatchingNodeSet nodeSet) {
+		if (pattern.findReferences) {
+			if (node instanceof SingleTypeReference) { // Type parameter cannot be qualified
+				if (matchesName(this.pattern.name, ((SingleTypeReference) node).token)) {
+					int level = ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+					return nodeSet.addMatch(node, level);
+				}
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+
+	/*
+	 * Verify whether a type parameter matches name pattern.
+	 */
+	public int match(TypeParameter node, MatchingNodeSet nodeSet) {
+		if (pattern.findDeclarations) {
+			if (matchesName(this.pattern.name, node.name)) {
+				int level = ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH;
+				return nodeSet.addMatch(node, level);
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	/*
+	 * While searching for references, need to match all containers as we can have references in javadoc comments.
+	 * Otherwise, only class or method container can declare type parameters.
+	 */
+	protected int matchContainer() {
+		if (pattern.findReferences) {
+			return ALL_CONTAINER;
+		}
+		return CLASS_CONTAINER | METHOD_CONTAINER;
+	}
+
+	/*
+	 * Verify that a type variable binding match pattern infos.
+	 * For types, only look at declaring member name.
+	 * For methods, also look at declaring class and parameters type names
+	 */
+	protected int matchTypeParameter(TypeVariableBinding variable, boolean matchName) {
+		if (variable == null || variable.declaringElement == null) return INACCURATE_MATCH;
+		if (variable.declaringElement instanceof ReferenceBinding) {
+			ReferenceBinding refBinding  = (ReferenceBinding) variable.declaringElement;
+			if (matchesName(refBinding.sourceName, pattern.declaringMemberName)) {
+				return ACCURATE_MATCH;
+			}
+		} else if (variable.declaringElement instanceof MethodBinding) {
+			MethodBinding methBinding  = (MethodBinding) variable.declaringElement;
+			if (matchesName(methBinding.declaringClass.sourceName, pattern.methodDeclaringClassName) &&
+				(methBinding.isConstructor() || matchesName(methBinding.selector, pattern.declaringMemberName))) {
+				int length = pattern.methodArgumentTypes==null ? 0 : pattern.methodArgumentTypes.length;
+				if (methBinding.parameters == null) {
+					if (length == 0) return ACCURATE_MATCH;
+				} else if (methBinding.parameters.length == length){
+					for (int i=0; i<length; i++) {
+						if (!matchesName(methBinding.parameters[i].shortReadableName(), pattern.methodArgumentTypes[i])) {
+							return IMPOSSIBLE_MATCH;
+						}
+					}
+					return ACCURATE_MATCH;
+				}
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	protected int referenceType() {
+		return IJavaElement.TYPE_PARAMETER;
+	}
+
+	/*
+	 * Resolve level for a possible matching node.
+	 * Only type references while searching references and type parameters
+	 * while searching declarations are valid.
+	 */
+	public int resolveLevel(ASTNode possibleMatchingNode) {
+		if (this.pattern.findReferences) {
+			if (possibleMatchingNode instanceof SingleTypeReference) {
+				return resolveLevel(((SingleTypeReference) possibleMatchingNode).resolvedType);
+			}
+		}
+		if (this.pattern.findDeclarations) {
+			if (possibleMatchingNode instanceof TypeParameter) {
+				return matchTypeParameter(((TypeParameter) possibleMatchingNode).binding, true);
+			}
+		}
+		return IMPOSSIBLE_MATCH;
+	}
+
+	/*
+	 * Resolve level for a binding.
+	 * Only type variable bindings are valid.
+	 */
+	public int resolveLevel(Binding binding) {
+		if (binding == null) return INACCURATE_MATCH;
+		if (!(binding instanceof TypeVariableBinding)) return IMPOSSIBLE_MATCH;
+	
+		return matchTypeParameter((TypeVariableBinding) binding, true);
+	}
+
+	public String toString() {
+		return "Locator for " + this.pattern.toString(); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterPattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterPattern.java
new file mode 100644
index 0000000..071bdc8
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeParameterPattern.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchParticipant;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.index.Index;
+import org.eclipse.jdt.internal.core.search.IndexQueryRequestor;
+import org.eclipse.jdt.internal.core.search.JavaSearchScope;
+import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+/**
+ * Pattern to search type parameters.
+ *
+ * @since 3.1
+ */
+public class TypeParameterPattern extends JavaSearchPattern implements IIndexConstants {
+
+	protected boolean findDeclarations;
+	protected boolean findReferences;
+	protected char[] name;
+	protected ITypeParameter typeParameter;
+	protected char[] declaringMemberName;
+	protected char[] methodDeclaringClassName;
+	protected char[][] methodArgumentTypes;
+
+	/**
+	 * @param findDeclarations
+	 * @param findReferences
+	 * @param typeParameter
+	 * @param matchRule
+	 */
+	public TypeParameterPattern(boolean findDeclarations, boolean findReferences, ITypeParameter typeParameter, int matchRule) {
+		super(TYPE_PARAM_PATTERN, matchRule);
+
+		this.findDeclarations = findDeclarations; // set to find declarations & all occurences
+		this.findReferences = findReferences; // set to find references & all occurences
+		this.typeParameter = typeParameter;
+		this.name = typeParameter.getElementName().toCharArray(); // store type parameter name
+		IMember member = typeParameter.getDeclaringMember();
+		this.declaringMemberName = member.getElementName().toCharArray(); // store type parameter declaring member name
+		
+		// For method type parameter, store also declaring class name and parameters type names
+		if (member instanceof IMethod) {
+			IMethod method = (IMethod) member;
+			this.methodDeclaringClassName = method.getParent().getElementName().toCharArray();
+			String[] parameters = method.getParameterTypes();
+			int length = parameters.length;
+			this.methodArgumentTypes = new char[length][];
+			for (int i=0; i<length; i++) {
+				this.methodArgumentTypes[i] = Signature.toCharArray(parameters[i].toCharArray());
+			}
+		}
+	}
+
+	/*
+	 * Same than LocalVariablePattern.
+	 */
+	public void findIndexMatches(Index index, IndexQueryRequestor requestor, SearchParticipant participant, IJavaSearchScope scope, IProgressMonitor progressMonitor) {
+	    IPackageFragmentRoot root = (IPackageFragmentRoot) this.typeParameter.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+		String documentPath;
+		String relativePath;
+	    if (root.isArchive()) {
+ 	    	IType type = (IType) this.typeParameter.getAncestor(IJavaElement.TYPE);
+    	    relativePath = (type.getFullyQualifiedName('/')).replace('.', '/') + SuffixConstants.SUFFIX_STRING_class;
+	        documentPath = root.getPath() + IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR + relativePath;
+	    } else {
+			IPath path = this.typeParameter.getPath();
+	        documentPath = path.toString();
+			relativePath = Util.relativePath(path, 1/*remove project segment*/);
+	    }
+	
+		if (scope instanceof JavaSearchScope) {
+			JavaSearchScope javaSearchScope = (JavaSearchScope) scope;
+			// Get document path access restriction from java search scope
+			// Note that requestor has to verify if needed whether the document violates the access restriction or not
+			AccessRuleSet access = javaSearchScope.getAccessRuleSet(relativePath, index.containerPath);
+			if (access != JavaSearchScope.NOT_ENCLOSED) { // scope encloses the path
+				if (!requestor.acceptIndexMatch(documentPath, this, participant, access)) 
+					throw new OperationCanceledException();
+			}
+		} else if (scope.encloses(documentPath)) {
+			if (!requestor.acceptIndexMatch(documentPath, this, participant, null)) 
+				throw new OperationCanceledException();
+		}
+	}
+
+	protected StringBuffer print(StringBuffer output) {
+		if (this.findDeclarations) {
+			output.append(this.findReferences
+				? "TypeParamCombinedPattern: " //$NON-NLS-1$
+				: "TypeParamDeclarationPattern: "); //$NON-NLS-1$
+		} else {
+			output.append("TypeParamReferencePattern: "); //$NON-NLS-1$
+		}
+		output.append(typeParameter.toString());
+		return super.print(output);
+	}
+
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
index 8c8262f..8588f90 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -18,6 +18,7 @@
 import org.eclipse.jdt.internal.compiler.ast.*;
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.core.JavaElement;
 import org.eclipse.jdt.internal.core.util.SimpleSet;
 
 public class TypeReferenceLocator extends PatternLocator {
@@ -92,8 +93,7 @@
 	if (this.pattern.qualification == null) {
 		if (this.pattern.simpleName == null) return ACCURATE_MATCH;
 		char[][] tokens = importRef.tokens;
-		for (int i = 0, length = tokens.length; i < length; i++)
-			if (matchesName(this.pattern.simpleName, tokens[i])) return ACCURATE_MATCH;
+		if (matchesName(this.pattern.simpleName, tokens[tokens.length-1])) return ACCURATE_MATCH;
 	} else {
 		char[][] tokens = importRef.tokens;
 		char[] qualifiedPattern = this.pattern.simpleName == null
@@ -124,10 +124,27 @@
 			FieldBinding fieldBinding = (FieldBinding) binding;
 			if (!fieldBinding.isStatic()) return;
 			refBinding = fieldBinding.declaringClass;
+		} else if (binding instanceof MethodBinding) {
+			MethodBinding methodBinding = (MethodBinding) binding;
+			if (!methodBinding.isStatic()) return;
+			refBinding = methodBinding.declaringClass;
 		} else if (binding instanceof MemberTypeBinding) {
 			MemberTypeBinding memberBinding = (MemberTypeBinding) binding;
 			if (!memberBinding.isStatic()) return;
 		}
+		// resolve and report
+		int level = resolveLevel(refBinding);
+		if (level >= INACCURATE_MATCH) {
+			matchReportImportRef(
+				importRef, 
+				binding, 
+				locator.createImportHandle(importRef), 
+				level == ACCURATE_MATCH
+					? SearchMatch.A_ACCURATE
+					: SearchMatch.A_INACCURATE,
+				locator);
+		}
+		return;
 	}
 	super.matchLevelAndReportImportRef(importRef, refBinding, locator);
 }
@@ -145,26 +162,36 @@
 	}
 
 	// return if this is not necessary to report
-	if (this.pattern.isParameterized() && !this.isEquivalentMatch &&!this.isErasureMatch) {
+	if (this.pattern.hasTypeArguments() && !this.isEquivalentMatch &&!this.isErasureMatch) {
 		return;
 	}
+	
+	// Create search match
+	match = locator.newTypeReferenceMatch(element, binding, accuracy, importRef);
 
-	// set match rule
-	int rule = SearchMatch.A_ACCURATE;
-	boolean patternHasParameters = false;
-	if (this.pattern.isParameterized()) {
-		patternHasParameters = this.pattern.typeArguments[0] != null && this.pattern.typeArguments[0].length != 0;
-	}
-	if (patternHasParameters) { // binding has no type params, compatible erasure if pattern does
-		rule = SearchPattern.R_EQUIVALENT_MATCH | SearchPattern.R_ERASURE_MATCH;
+	// set match raw flag and rule
+	match.setRaw(true);
+	if (this.pattern.hasTypeArguments()) {
+		// binding is raw => only compatible erasure if pattern has type arguments
+		match.setRule(match.getRule() & (~SearchPattern.R_FULL_MATCH));
 	}
 	
 	// Try to find best selection for match
+	ReferenceBinding typeBinding = null;
+	boolean lastButOne = false;
 	if (binding instanceof ReferenceBinding) {
-		ReferenceBinding typeBinding = (ReferenceBinding) binding;
+		typeBinding = (ReferenceBinding) binding;
+	} else if (binding instanceof FieldBinding) { // may happen for static import
+		typeBinding = ((FieldBinding)binding).declaringClass;
+		lastButOne = importRef.isStatic() && !importRef.onDemand;
+	} else if (binding instanceof MethodBinding) { // may happen for static import
+		typeBinding = ((MethodBinding)binding).declaringClass;
+		lastButOne = importRef.isStatic() && !importRef.onDemand;
+	}
+	if (typeBinding != null) {
 		int lastIndex = importRef.tokens.length - 1;
-		if (importRef.isStatic() && !importRef.onDemand && !typeBinding.isMemberType()) {
-			// for field static import, do not use last token
+		if (lastButOne) {
+			// for field or method static import, use last but one token
 			lastIndex--;
 		}
 		if (typeBinding instanceof ProblemReferenceBinding) {
@@ -180,19 +207,14 @@
 					// index now depends on pattern type signature
 					int index = lastIndex;
 					if (this.pattern.qualification != null) {
-						if (this.pattern.typeSignatures != null) {
-							if (this.pattern.typeSignatures.length > 1) {
-								index = lastIndex - (this.pattern.typeSignatures.length - 1);
-							}
-						} else {
-							index = lastIndex - this.pattern.segmentsSize;
-						}
+						index = lastIndex - this.pattern.segmentsSize;
 					}
 					if (index < 0) index = 0;
 					int start = (int) ((positions[index]) >>> 32);
 					int end = (int) positions[lastIndex];
 					// report match
-					SearchMatch match = locator.newTypeReferenceMatch(element, accuracy, start, end-start+1, rule, importRef);
+					match.setOffset(start);
+					match.setLength(end-start+1);
 					locator.report(match);
 				}
 				return;
@@ -201,49 +223,52 @@
 			typeBinding = typeBinding.enclosingType();
 		}
 	}
-	locator.reportAccurateTypeReference(importRef, this.pattern.simpleName, element, accuracy, rule);
+	locator.reportAccurateTypeReference(match, importRef, this.pattern.simpleName);
 }
-protected void matchReportReference(ArrayTypeReference arrayRef, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ArrayTypeReference arrayRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	if (this.pattern.simpleName == null) {
 		// TODO (frederic) need to add a test for this case while searching generic types...
 		if (locator.encloses(element)) {
 			int offset = arrayRef.sourceStart;
-			SearchMatch match = locator.newTypeReferenceMatch(element, accuracy, offset, arrayRef.sourceEnd-offset+1, arrayRef);
+			match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, arrayRef.sourceEnd-offset+1, arrayRef);
 			locator.report(match);
 			return;
 		}
 	}
+	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, arrayRef);
 	if (arrayRef.resolvedType != null) {
-		matchReportReference(arrayRef, element, accuracy, arrayRef.sourceStart, arrayRef.sourceEnd, -1, arrayRef.resolvedType.leafComponentType(), locator);
+		matchReportReference(arrayRef, -1, arrayRef.resolvedType.leafComponentType(), locator);
 		return;
 	}
-	locator.reportAccurateTypeReference(arrayRef, this.pattern.simpleName, element, accuracy);
+	locator.reportAccurateTypeReference(match, arrayRef, this.pattern.simpleName);
 }
-protected void matchReportReference(ASTNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	if (this.isDeclarationOfReferencedTypesPattern) {
 		if ((element = findElement(element, accuracy)) != null)
 			reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes);
 		return;
 	}
+	
+	// Create search match
+	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference);
 
+	// Report match depending on reference type
 	if (reference instanceof QualifiedNameReference)
-		matchReportReference((QualifiedNameReference) reference, element, accuracy, locator);
+		matchReportReference((QualifiedNameReference) reference, element, elementBinding, accuracy, locator);
 	else if (reference instanceof QualifiedTypeReference)
-		matchReportReference((QualifiedTypeReference) reference, element, accuracy, locator);
+		matchReportReference((QualifiedTypeReference) reference, element, elementBinding, accuracy, locator);
 	else if (reference instanceof ArrayTypeReference)
-		matchReportReference((ArrayTypeReference) reference, element, accuracy, locator);
+		matchReportReference((ArrayTypeReference) reference, element, elementBinding, accuracy, locator);
 	else {
 		TypeBinding typeBinding = reference instanceof Expression ? ((Expression)reference).resolvedType : null;
 		if (typeBinding != null) {
-			matchReportReference((Expression)reference, element, accuracy, reference.sourceStart, reference.sourceEnd, -1, typeBinding, locator);
+			matchReportReference((Expression)reference, -1, typeBinding, locator);
 			return;
 		}
-		int offset = reference.sourceStart;
-		SearchMatch match = locator.newTypeReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference);
 		locator.report(match);
 	}
 }
-protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	Binding binding = qNameRef.binding;
 	TypeBinding typeBinding = null;
 	int lastIndex = qNameRef.tokens.length - 1;
@@ -273,6 +298,10 @@
 		typeBinding = pbBinding.original;
 		lastIndex = pbBinding.compoundName.length - 1;
 	}
+
+	// Create search match to report
+	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef);
+
 	// try to match all enclosing types for which the token matches as well.
 	if (typeBinding instanceof ReferenceBinding) {
 		ReferenceBinding refBinding = (ReferenceBinding) typeBinding; 
@@ -282,7 +311,8 @@
 					long[] positions = qNameRef.sourcePositions;
 					int start = (int) ((positions[this.pattern.qualification == null ? lastIndex : 0]) >>> 32);
 					int end = (int) positions[lastIndex];
-					SearchMatch match = locator.newTypeReferenceMatch(element, accuracy, start, end-start+1, qNameRef);
+					match.setOffset(start);
+					match.setLength(end-start+1);
 					locator.report(match);
 				}
 				return;
@@ -291,9 +321,9 @@
 			refBinding = refBinding.enclosingType();
 		}
 	}
-	locator.reportAccurateTypeReference(qNameRef, this.pattern.simpleName, element, accuracy);
+	locator.reportAccurateTypeReference(match, qNameRef, this.pattern.simpleName);
 }
-protected void matchReportReference(QualifiedTypeReference qTypeRef, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
+protected void matchReportReference(QualifiedTypeReference qTypeRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException {
 	TypeBinding typeBinding = qTypeRef.resolvedType;
 	int lastIndex = qTypeRef.tokens.length - 1;
 	if (typeBinding instanceof ArrayBinding)
@@ -303,6 +333,10 @@
 		typeBinding = pbBinding.original;
 		lastIndex = pbBinding.compoundName.length - 1;
 	}
+
+	// Create search match to report
+	match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef);
+
 	// try to match all enclosing types for which the token matches as well
 	if (typeBinding instanceof ReferenceBinding) {
 		ReferenceBinding refBinding = (ReferenceBinding) typeBinding; 
@@ -313,20 +347,16 @@
 					// index now depends on pattern type signature
 					int index = lastIndex;
 					if (this.pattern.qualification != null) {
-						if (this.pattern.typeSignatures != null) {
-							if (this.pattern.typeSignatures.length > 1) {
-								index = lastIndex - (this.pattern.typeSignatures.length - 1);
-							}
-						} else {
-							index = lastIndex - this.pattern.segmentsSize;
-						}
+						index = lastIndex - this.pattern.segmentsSize;
 					}
 					if (index < 0) index = 0;
 					int start = (int) ((positions[index]) >>> 32);
 					int end = (int) positions[lastIndex];
+					match.setOffset(start);
+					match.setLength(end-start+1);
 
 					//  Look if there's a need to special report for parameterized type
-					matchReportReference(qTypeRef, element, accuracy, start, end, lastIndex, refBinding, locator);
+					matchReportReference(qTypeRef, lastIndex, refBinding, locator);
 				}
 				return;
 			}
@@ -334,43 +364,24 @@
 			refBinding = refBinding.enclosingType();
 		}
 	}
-	locator.reportAccurateTypeReference(qTypeRef, this.pattern.simpleName, element, accuracy);
+	locator.reportAccurateTypeReference(match, qTypeRef, this.pattern.simpleName);
 }
-void matchReportReference(Expression expr, IJavaElement element, int accuracy, int start, int end, int lastIndex, TypeBinding refBinding, MatchLocator locator) throws CoreException {
+void matchReportReference(Expression expr, int lastIndex, TypeBinding refBinding, MatchLocator locator) throws CoreException {
 
 	// Look if there's a need to special report for parameterized type
-	int rule = SearchPattern.R_EXACT_MATCH;
-	int refinedAccuracy = accuracy;
-	boolean patternHasParameters = false;
-	if (this.pattern.isParameterized()) {
-		patternHasParameters = this.pattern.typeArguments[0] != null && this.pattern.typeArguments[0].length != 0;
-	}
 	if (refBinding.isParameterizedType() || refBinding.isRawType()) {
 
 		// Try to refine accuracy
 		ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)refBinding;
-		refinedAccuracy = refineAccuracy(accuracy, parameterizedBinding, this.pattern.typeArguments, this.pattern.typeSignatures==null, 0, locator);
+		updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator);
 		
 		// See whether it is necessary to report or not
-		boolean report = refinedAccuracy != -1; // impossible match
-		if (report && (refinedAccuracy & SearchPattern.R_ERASURE_MATCH) != 0) { // erasure match
-			if ((refinedAccuracy & SearchPattern.R_EQUIVALENT_MATCH) != 0) { // raw match
-				report = this.isEquivalentMatch || this.isErasureMatch; // report only if pattern is equivalent or erasure
-			} else {
-				report = this.isErasureMatch; // report only if pattern is erasure
-			}
-		}
-		else if (report && (refinedAccuracy & SearchPattern.R_EQUIVALENT_MATCH) != 0) { // equivalent match
-			report  = this.isEquivalentMatch || this.isErasureMatch; // report only if pattern is equivalent or erasure
-		}
-		if (!report)return;
-
-		// Set rule
-		rule |= refinedAccuracy & RULE_MASK;
-		refinedAccuracy = refinedAccuracy & (~RULE_MASK);
+		if (match.getRule() == 0) return; // impossible match
+		boolean report = (this.isErasureMatch && match.isErasure()) || (this.isEquivalentMatch && match.isEquivalent()) || match.isExact();
+		if (!report) return;
 
 		// Make a special report for parameterized types if necessary
-		 if (refBinding.isParameterizedType() && this.pattern.isParameterized())  {
+		 if (refBinding.isParameterizedType() && this.pattern.hasTypeArguments())  {
 			TypeReference typeRef = null;
 			TypeReference[] typeArguments = null;
 			if (expr instanceof ParameterizedQualifiedTypeReference) {
@@ -382,19 +393,18 @@
 				typeArguments = ((ParameterizedSingleTypeReference) expr).typeArguments;
 			}
 			if (typeRef != null) {
-				locator.reportAccurateParameterizedTypeReference(typeRef, start, lastIndex, typeArguments, element, refinedAccuracy, rule);
+				locator.reportAccurateParameterizedTypeReference(match, typeRef, lastIndex, typeArguments);
 				return;
 			}
 		}
-	} else if (patternHasParameters) { // binding has no type params, compatible erasure if pattern does
-		rule = SearchPattern.R_ERASURE_MATCH;
+	} else if (this.pattern.hasTypeArguments()) { // binding has no type params, compatible erasure if pattern does
+		match.setRule(SearchPattern.R_ERASURE_MATCH);
 	}
 
 	// Report match
-	if (expr instanceof ArrayTypeReference)
-		locator.reportAccurateTypeReference(expr, this.pattern.simpleName, element, refinedAccuracy, rule);
-	else {
-		SearchMatch match = locator.newTypeReferenceMatch(element, refinedAccuracy, start, end-start+1, rule, expr);
+	if (expr instanceof ArrayTypeReference) {
+		locator.reportAccurateTypeReference(match, expr, this.pattern.simpleName);
+	} else {
 		locator.report(match);
 	}
 }
@@ -465,7 +475,7 @@
 	while (maxType >= 0 && type != null) {
 		if (!knownTypes.includes(type)) {
 			if (isBinary) {
-				locator.reportBinaryMemberDeclaration(resource, type, info, SearchMatch.A_ACCURATE);
+				locator.reportBinaryMemberDeclaration(resource, type, typeBinding, info, SearchMatch.A_ACCURATE);
 			} else {
 				if (typeBinding instanceof ParameterizedTypeBinding)
 					typeBinding = ((ParameterizedTypeBinding) typeBinding).type;
@@ -473,7 +483,7 @@
 				if (scope != null) {
 					TypeDeclaration typeDecl = scope.referenceContext;
 					int offset = typeDecl.sourceStart;
-					SearchMatch match = new TypeDeclarationMatch(type, SearchMatch.A_ACCURATE, offset, typeDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
+					match = new TypeDeclarationMatch(((JavaElement) type).resolved(typeBinding), SearchMatch.A_ACCURATE, offset, typeDecl.sourceEnd-offset+1, locator.getParticipant(), resource);
 					locator.report(match);
 				}
 			}
@@ -583,7 +593,7 @@
 	return resolveLevelForType(
 			this.pattern.simpleName,
 			this.pattern.qualification,
-			this.pattern.typeArguments,
+			this.pattern.getTypeArguments(),
 			0,
 			typeBinding);
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java
index 3fec794..d250d44 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferencePattern.java
@@ -1,161 +1,128 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.search.matching;
 
-import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeParameter;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.search.SearchPattern;
 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
+import org.eclipse.jdt.internal.core.util.Util;
 
-public class TypeReferencePattern extends AndPattern implements IIndexConstants {
-
-protected char[] qualification;
-protected char[] simpleName;
+	public class TypeReferencePattern extends AndPattern implements IIndexConstants {
 	
-protected char[] currentCategory;
-
-/* Optimization: case where simpleName == null */
-public int segmentsSize;
-protected char[][] segments;
-protected int currentSegment;
-
-protected static char[][] CATEGORIES = { REF };
-
-public TypeReferencePattern(char[] qualification, char[] simpleName, int matchRule) {
-	this(matchRule);
-
-	this.qualification = isCaseSensitive() ? qualification : CharOperation.toLowerCase(qualification);
-	this.simpleName = isCaseSensitive() ? simpleName : CharOperation.toLowerCase(simpleName);
-
-	if (simpleName == null)
-		this.segments = this.qualification == null ? ONE_STAR_CHAR : CharOperation.splitOn('.', this.qualification);
-	else
-		this.segments = null;
+	protected char[] qualification;
+	protected char[] simpleName;
+		
+	protected char[] currentCategory;
 	
-	if (this.segments == null)
-		if (this.qualification == null)
-			this.segmentsSize =  0;
+	/* Optimization: case where simpleName == null */
+	public int segmentsSize;
+	protected char[][] segments;
+	protected int currentSegment;
+
+	protected static char[][] CATEGORIES = { REF };
+	
+	public TypeReferencePattern(char[] qualification, char[] simpleName, int matchRule) {
+		this(matchRule);
+	
+		this.qualification = isCaseSensitive() ? qualification : CharOperation.toLowerCase(qualification);
+		this.simpleName = isCaseSensitive() ? simpleName : CharOperation.toLowerCase(simpleName);
+	
+		if (simpleName == null)
+			this.segments = this.qualification == null ? ONE_STAR_CHAR : CharOperation.splitOn('.', this.qualification);
 		else
-			this.segmentsSize =  CharOperation.occurencesOf('.', this.qualification) + 1;
-	else
-		this.segmentsSize = this.segments.length;
-
-	((InternalSearchPattern)this).mustResolve = true; // always resolve (in case of a simple name reference being a potential match)
-}
-/*
- * Instanciate a type reference pattern with additional information for generics search
- */
-public TypeReferencePattern(char[] qualification, char[] simpleName, String signature, int matchRule) {
-	this(qualification, simpleName,matchRule);
-
-	if (signature != null) computeSignature(signature);
-}
-public TypeReferencePattern(char[] qualification, char[] simpleName, IType type, int matchRule) {
-	this(qualification, simpleName, matchRule);
-
-	this.typeArguments = typeParameterNames(type);
-}
-TypeReferencePattern(int matchRule) {
-	super(TYPE_REF_PATTERN, matchRule);
-}
-public void decodeIndexKey(char[] key) {
-	this.simpleName = key;
-}
-public SearchPattern getBlankPattern() {
-	return new TypeReferencePattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
-}
-public char[] getIndexKey() {
-	if (this.simpleName != null)
-		return this.simpleName;
-
-	// Optimization, eg. type reference is 'org.eclipse.jdt.core.*'
-	if (this.currentSegment >= 0) 
-		return this.segments[this.currentSegment];
-	return null;
-}
-public char[][] getIndexCategories() {
-	return CATEGORIES;
-}
-protected boolean hasNextQuery() {
-	if (this.segments == null) return false;
-
-	// Optimization, eg. type reference is 'org.eclipse.jdt.core.*'
-	// if package has at least 4 segments, don't look at the first 2 since they are mostly
-	// redundant (eg. in 'org.eclipse.jdt.core.*' 'org.eclipse' is used all the time)
-	return --this.currentSegment >= (this.segments.length >= 4 ? 2 : 0);
-}
-public boolean matchesDecodedKey(SearchPattern decodedPattern) {
-	return true; // index key is not encoded so query results all match
-}
-protected void resetQuery() {
-	/* walk the segments from end to start as it will find less potential references using 'lang' than 'java' */
-	if (this.segments != null)
-		this.currentSegment = this.segments.length - 1;
-}
-protected StringBuffer print(StringBuffer output) {
-	output.append("TypeReferencePattern: qualification<"); //$NON-NLS-1$
-	if (qualification != null) 
-		output.append(qualification);
-	else
-		output.append("*"); //$NON-NLS-1$
-	output.append(">, type<"); //$NON-NLS-1$
-	if (simpleName != null) 
-		output.append(simpleName);
-	else
-		output.append("*"); //$NON-NLS-1$
-	output.append(">"); //$NON-NLS-1$
-	return super.print(output);
-}
-/*
- * Returns the type parameter names of the given type.
- */
-private char[][][] typeParameterNames(IType type) {
-	char[][][] typeParameters = new char[10][][];
-	int ptr = -1;
-	boolean hasParameters = false;
-	try {
-		IJavaElement parent = type;
-		ITypeParameter[] parameters = null;
-		while (parent != null) {
-			if (parent.getElementType() != IJavaElement.TYPE) {
-				if (!hasParameters) return null;
-				if (++ptr < typeParameters.length)
-					System.arraycopy(typeParameters, 0, typeParameters = new char[ptr][][], 0, ptr);
-				return typeParameters;
+			this.segments = null;
+		
+		if (this.segments == null)
+			if (this.qualification == null)
+				this.segmentsSize =  0;
+			else
+				this.segmentsSize =  CharOperation.occurencesOf('.', this.qualification) + 1;
+		else
+			this.segmentsSize = this.segments.length;
+	
+		((InternalSearchPattern)this).mustResolve = true; // always resolve (in case of a simple name reference being a potential match)
+	}
+	/*
+	 * Instanciate a type reference pattern with additional information for generics search
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, String typeSignature, int matchRule) {
+		this(qualification, simpleName,matchRule);
+		if (typeSignature != null) {
+			// store type signatures and arguments
+			this.typeSignatures = Util.splitTypeLevelsSignature(typeSignature);
+			setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
+			if (hasTypeArguments()) {
+				this.segmentsSize = getTypeArguments().length + CharOperation.occurencesOf('/', this.typeSignatures[0]) - 1;
 			}
-			if (++ptr > typeParameters.length) {
-				System.arraycopy(typeParameters, 0, typeParameters = new char[typeParameters.length+10][][], 0, ptr);
-			}
-			IType parentType = (IType) parent;
-			parameters = parentType.getTypeParameters();
-			int length = parameters==null ? 0 : parameters.length;
-			if (length > 0) {
-				hasParameters = true;
-				typeParameters[ptr] = new char[length][];
-				for (int i=0; i<length; i++)
-					typeParameters[ptr][i] = Signature.createTypeSignature(parameters[i].getElementName(), false).toCharArray();
-			}
-			parent = parent.getParent();
 		}
 	}
-	catch (JavaModelException jme) {
+	/*
+	 * Instanciate a type reference pattern with additional information for generics search
+	 */
+	public TypeReferencePattern(char[] qualification, char[] simpleName, IType type, int matchRule) {
+		this(qualification, simpleName,matchRule);
+		storeTypeSignaturesAndArguments(type);
+	}
+	TypeReferencePattern(int matchRule) {
+		super(TYPE_REF_PATTERN, matchRule);
+	}
+	public void decodeIndexKey(char[] key) {
+		this.simpleName = key;
+	}
+	public SearchPattern getBlankPattern() {
+		return new TypeReferencePattern(R_EXACT_MATCH | R_CASE_SENSITIVE);
+	}
+	public char[] getIndexKey() {
+		if (this.simpleName != null)
+			return this.simpleName;
+	
+		// Optimization, eg. type reference is 'org.eclipse.jdt.core.*'
+		if (this.currentSegment >= 0) 
+			return this.segments[this.currentSegment];
 		return null;
 	}
-	if (!hasParameters) return null;
-	if (++ptr < typeParameters.length)
-		System.arraycopy(typeParameters, 0, typeParameters = new char[ptr][][], 0, ptr);
-	return typeParameters;
-}
+	public char[][] getIndexCategories() {
+		return CATEGORIES;
+	}
+	protected boolean hasNextQuery() {
+		if (this.segments == null) return false;
+	
+		// Optimization, eg. type reference is 'org.eclipse.jdt.core.*'
+		// if package has at least 4 segments, don't look at the first 2 since they are mostly
+		// redundant (eg. in 'org.eclipse.jdt.core.*' 'org.eclipse' is used all the time)
+		return --this.currentSegment >= (this.segments.length >= 4 ? 2 : 0);
+	}
+
+	public boolean matchesDecodedKey(SearchPattern decodedPattern) {
+		return true; // index key is not encoded so query results all match
+	}
+
+	protected void resetQuery() {
+		/* walk the segments from end to start as it will find less potential references using 'lang' than 'java' */
+		if (this.segments != null)
+			this.currentSegment = this.segments.length - 1;
+	}
+	protected StringBuffer print(StringBuffer output) {
+		output.append("TypeReferencePattern: qualification<"); //$NON-NLS-1$
+		if (qualification != null) 
+			output.append(qualification);
+		else
+			output.append("*"); //$NON-NLS-1$
+		output.append(">, type<"); //$NON-NLS-1$
+		if (simpleName != null) 
+			output.append(simpleName);
+		else
+			output.append("*"); //$NON-NLS-1$
+		output.append(">"); //$NON-NLS-1$
+		return super.print(output);
+	}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java
index c8a7f9c..cb35bfc 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariableLocator.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java
index 61276ed..c7f04f3 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/VariablePattern.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java
index c6f0832..554442f 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/IJob.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
index 9b28f6c..e523a16 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -15,6 +15,7 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.jdt.internal.core.util.Util;
 
 public abstract class JobManager implements Runnable {
@@ -233,7 +234,7 @@
 									Util.verbose("-> NOT READY - waiting until ready - " + searchJob);//$NON-NLS-1$
 								if (subProgress != null) {
 									subProgress.subTask(
-										Util.bind("manager.filesToIndex", Integer.toString(awaitingWork))); //$NON-NLS-1$
+										Messages.bind(Messages.manager_filesToIndex, Integer.toString(awaitingWork))); 
 									subProgress.worked(1);
 								}
 								previousJob = currentJob;
@@ -317,7 +318,7 @@
 				protected IStatus run(IProgressMonitor monitor) {
 					int awaitingJobsCount;
 					while ((awaitingJobsCount = awaitingJobsCount()) > 0) {
-						monitor.subTask(Util.bind("manager.filesToIndex", Integer.toString(awaitingJobsCount))); //$NON-NLS-1$
+						monitor.subTask(Messages.bind(Messages.manager_filesToIndex, Integer.toString(awaitingJobsCount))); 
 						try {
 							Thread.sleep(500);
 						} catch (InterruptedException e) {
@@ -360,7 +361,7 @@
 					try {
 						this.executing = true;
 						if (progressJob == null) {
-							progressJob = new ProgressJob(Util.bind("manager.indexingInProgress")); //$NON-NLS-1$
+							progressJob = new ProgressJob(Messages.manager_indexingInProgress); 
 							progressJob.setPriority(Job.LONG);
 							progressJob.setSystem(true);
 							progressJob.schedule();