Basic merge with v_B72_R37x incl. support for Java7.
tests.otjld report 4 new failures, mostly due to missing parser support for LTR for catch parameters.
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
index 33ff94b..4ead49a 100644
--- a/org.eclipse.jdt.core/.settings/.api_filters
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -1,6 +1,362 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <component id="org.eclipse.jdt.core" version="2">
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.objectteams.otdt.core.PhantomType">
+    <resource path="META-INF/MANIFEST.MF">
+        <filter comment="Merge Java7 support into R3_7_maintenance" id="924844039">
+             <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="3.7.0"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="compiler/org/eclipse/jdt/core/compiler/CharOperation.java" type="org.eclipse.jdt.core.compiler.CharOperation">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="compareTo(char[], char[], int, int)"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="compiler/org/eclipse/jdt/core/compiler/IProblem.java" type="org.eclipse.jdt.core.compiler.IProblem">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="AssignmentToMultiCatchParameter"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="AssignmentToResource"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="AutoManagedResourceNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="BinaryLiteralNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="CannotInferElidedTypes"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="CannotUseDiamondWithAnonymousClasses"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="CannotUseDiamondWithExplicitTypeArguments"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="DiamondNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="DuplicateInheritedMethods"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="IllegalHexaLiteral"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="IllegalUnderscorePosition"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="IncorrectSwitchType17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="InvalidBinary"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="InvalidUnionTypeReferenceSequence"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="MultiCatchNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="PolymorphicMethodNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="PotentialHeapPollutionFromVararg"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="RedundantSpecificationOfTypeArguments"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="ResourceHasToImplementAutoCloseable"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="SafeVarargsOnFixedArityMethod"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="SafeVarargsOnNonFinalInstanceMethod"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="SwitchOnStringsNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="UnderscoresInLiteralsNotBelow17"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1210056707">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="UnhandledExceptionOnAutoClose"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/AST.java" type="org.eclipse.jdt.core.dom.AST">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="JLS4"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="newUnionType()"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/ASTMatcher.java" type="org.eclipse.jdt.core.dom.ASTMatcher">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="match(UnionType, Object)"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/ASTNode.java" type="org.eclipse.jdt.core.dom.ASTNode">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="UNION_TYPE"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/ASTVisitor.java" type="org.eclipse.jdt.core.dom.ASTVisitor">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="endVisit(UnionType)"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="visit(UnionType)"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/ClassInstanceCreation.java" type="org.eclipse.jdt.core.dom.ClassInstanceCreation">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="isResolvedTypeInferredFromExpectedType()"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/TryStatement.java" type="org.eclipse.jdt.core.dom.TryStatement">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="RESOURCES_PROPERTY"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="resources()"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/Type.java" type="org.eclipse.jdt.core.dom.Type">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="isUnionType()"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="dom/org/eclipse/jdt/core/dom/UnionType.java" type="org.eclipse.jdt.core.dom.UnionType">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1109393411">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="org.eclipse.jdt.core.dom.UnionType"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java" type="org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="FORMATTER_WRAP_BEFORE_OR_OPERATOR_MULTICATCH"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="model/org/eclipse/jdt/core/CompletionProposal.java" type="org.eclipse.jdt.core.CompletionProposal">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="canUseDiamond(CompletionContext)"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="model/org/eclipse/jdt/core/JavaCore.java" type="org.eclipse.jdt.core.JavaCore">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="model/org/eclipse/jdt/core/Signature.java" type="org.eclipse.jdt.core.Signature">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="C_INTERSECTION"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="INTERSECTION_TYPE_SIGNATURE"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="createIntersectionTypeSignature(String[])"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="createIntersectionTypeSignature(char[][])"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="getIntersectionTypeBounds(String)"/>
+           </message_arguments>
+       </filter>
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="getIntersectionTypeBounds(char[])"/>
+           </message_arguments>
+       </filter>
+   </resource>
+   <resource path="model/org/eclipse/jdt/core/compiler/ReconcileContext.java" type="org.eclipse.jdt.core.compiler.ReconcileContext">
+       <filter comment="new APIs added for Java7 support post 3.7.0" id="1142947843">
+           <message_arguments>
+               <message_argument value="3.7.1"/>
+               <message_argument value="getAST4()"/>
+             </message_arguments>
+       </filter>
+   </resource>
+   <resource path="model/org/eclipse/objectteams/otdt/internal/core/PhantomType.java" type="org.eclipse.objectteams.otdt.core.PhantomType">
         <filter comment="type PhantomType was moved to internal package" id="305324134">
             <message_arguments>
                 <message_argument value="org.eclipse.objectteams.otdt.core.PhantomType"/>
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 07a6354..e88f4ac 100644
--- a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,4 @@
-#Wed Feb 02 11:55:06 EST 2011
+#Wed Feb 02 11:25:08 EST 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.core.builder.cleanOutputFolder=clean
 org.eclipse.jdt.core.builder.duplicateResourceTask=warning
diff --git a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs
index e069008..2dcd706 100644
--- a/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs
+++ b/org.eclipse.jdt.core/.settings/org.eclipse.jdt.launching.prefs
@@ -1,3 +1,3 @@
-#Wed Feb 02 11:55:05 EST 2011
+#Wed Feb 02 11:25:08 EST 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=error
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index a95409b..84de28d 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.core; singleton:=true
-Bundle-Version: 3.7.0.v_OTDT_r201_qualifier
+Bundle-Version: 3.7.1.v_OTDT_r201_qualifier
 Bundle-Activator: org.eclipse.jdt.core.JavaCore
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.core/about.html b/org.eclipse.jdt.core/about.html
index 0b5c1d1..bfb21be 100644
--- a/org.eclipse.jdt.core/about.html
+++ b/org.eclipse.jdt.core/about.html
@@ -8,7 +8,7 @@
 <body lang="EN-US">
 <h2>About This Content</h2>
  
-<p>May 11, 2006</p>	
+<p>March 17, 2011</p>
 <h3>License</h3>
 
 <p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
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 7fc487f..47bf67c 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
@@ -3417,7 +3417,7 @@
 			break;
 		case 'e' :
 			if (token.equals("enumSwitch") //$NON-NLS-1$
-					|| token.equals("incomplete-switch") /*backward compatible*/) { //$NON-NLS-1$
+					|| token.equals("incomplete-switch")) { //$NON-NLS-1$
 				setSeverity(CompilerOptions.OPTION_ReportIncompleteEnumSwitch, severity, isEnabling);
 				return;
 			} else if (token.equals("emptyBlock")) {//$NON-NLS-1$
@@ -3705,9 +3705,11 @@
 				setSeverity(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, severity, isEnabling);
 				setSeverity(CompilerOptions.OPTION_ReportUnusedLabel, severity, isEnabling);
 				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
 				return;
 			} else if (token.equals("unusedTypeArgs")) { //$NON-NLS-1$
 				setSeverity(CompilerOptions.OPTION_ReportUnusedTypeArgumentsForMethodInvocation, severity, isEnabling);
+				setSeverity(CompilerOptions.OPTION_ReportRedundantSpecificationOfTypeArguments, severity, isEnabling);
 				return;
 			} else if (token.equals("unavoidableGenericProblems")) { //$NON-NLS-1$
 				this.options.put(
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 66d9f54..65388a0 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,12 +1,12 @@
 #Format: compiler.name = word1 word2 word3
 compiler.name = Eclipse Compiler for Java(TM)
 #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.B61, 3.7.0
-compiler.copyright = Copyright IBM Corp 2000, 2010. All rights reserved.
+compiler.version = 0.B72_R37x, 3.7.1
+compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved.
 
 ###{ObjectTeams:
 otdtc.name = Extension for Object Teams
-otdtc.version = 2.0.0 $LastChangedRevision$ $LastChangedDate$
+otdtc.version = 2.0.1 $LastChangedRevision$ $LastChangedDate$
 otdtc.copyright = Copyright by TU Berlin, Fraunhofer FIRST and others, 2004, 2011.
 ### SH}
 ### progress
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index a90e2ac..2a293f8 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -41,11 +41,319 @@
 	</td>
   </tr>
 </table>
+<a name="v_B72_R37x"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7.1 - July 28, 2011 - 3.7.1
+<br>Project org.eclipse.jdt.core v_B72_R37x
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B72">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Plugin version has been increment to 3.7.1</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353251">353251</a>
+[1.7] merging Java 7 work to R3_7_maintenance branch
+
+<a name="v_B71"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7.1 - July 27, 2011
+<br>Project org.eclipse.jdt.core v_B71
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B71">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351426">351426</a>
+[1.7][code assist] CompletionContext.getExpectedTypesKeys() returns wrong type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353137">353137</a>
+[1.7] Make sure TagBits.AnnotationSafeVarargs and AnnotationPolymorphicSignature are handled everywhere
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=353093">353093</a>
+IMethod#getAnnotations() doesn't return @SafeVarargs of java.util.Arrays#asList(T...)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352464">352464</a>
+[1.7] Incorrect Javadoc shown for reference of invokeExact
+
+<a name="v_B70"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7.1 - July 21, 2011
+<br>Project org.eclipse.jdt.core v_B70
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B70">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351498">351498</a>
+[model]java.util.ConcurrentModificationException upon startup
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352699">352699</a>
+[1.7][compiler] Improve error range for redundant type parameter warning
+
+<a name="v_B69"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7.1 - July 20, 2011
+<br>Project org.eclipse.jdt.core v_B69
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B69">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352665">352665</a>
+[1.6][compiler] Internal compiler Error: ArrayIndexOutOfBoundsException when compiling certain classes with outer access error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352553">352553</a>
+[1.7] 'char a\u200b' is being accepted in 1.6 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352496">352496</a>
+tests using wrong version of JCL
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300576">300576</a>
+NPE Computing type hierarchy when compliance doesn't match libraries
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352145">352145</a>
+[1.7][compiler] VerifyError with aload0 being involved into ConditionalExpression
+
+
+<a name="v_B68"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7.1 - July 14, 2011
+<br>Project org.eclipse.jdt.core v_B68
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B68">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>Added a new API in CompletionProposal to tell whether it diamond operator can be used (see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351444">351444</a> for details):
+<pre>
+/** 
+ * Returns whether it is safe to use the '<>' (diamond) operator in place of explicitly specifying
+ * type arguments for this proposal. 
+ * 
+ * This is only relevant for source level 1.7 or greater.
+ * 
+ * @param coreContext the completion context associated with the proposal
+ * @since 3.7
+ * @return <code>true</code> if it is safe to use the diamond operator for the constructor invocation, 
+ * <code>false</code> otherwise. Also returns <code>false</code> for source levels below 1.7
+ */
+public boolean canUseDiamond(CompletionContext coreContext);
+</pre>
+</li>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351965">351965</a>
+[1.7] CCE when using diamond in 1.4
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351444">351444</a>
+[1.7][content assist] Need to know whether I can use diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=352014">352014</a>
+\u1369 no longer accepted as a valid java identifier part
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351653">351653</a>
+[1.7][compiler]: VerifyError in try statement with finally and return statements
+
+<a name="v_B67"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - July 13, 2011
+<br>Project org.eclipse.jdt.core v_B67
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B67">cvs</a>).
+<h2>What's new in this drop</h2>
+<ul>
+<li>New Javacore option org.eclipse.jdt.core.JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS added to raise warning or error for redundant
+usage of type arguments when diamond operator can be used instead. (see details in bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340747">340747</a>):
+<pre>
+	/**
+	 * Compiler option ID: Reporting redundant specification of type arguments in class instance creation expressions.
+	 * When enabled, the compiler will issue an error or a warning if type arguments are used in a class instance creation,
+	 * when the '<>' operator can be used instead.
+	 *
+	 * This option only has an effect if the compiler compliance is 1.7 or greater.
+	 * 
+	 * Option id:<code>"org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"</code>
+	 * Possible values:<code>{ "error", "warning", "ignore" }</code>
+	 * Default:<code>"ignore"</code>
+	 * 
+	 * @since 3.7
+	 * @category CompilerOptionID
+	 */
+	public static final String COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS = PLUGIN_ID + ".compiler.problem.redundantSpecificationOfTypeArguments";
+	</pre>
+</li>
+<li>Added a new API in ClassInstanceCreation to tell whether the resolved type is inferred from the assignment context:
+<br>(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350897">350897</a> for details):
+<pre>
+	/**
+	 * Returns <code>true</code> if the resolved class type has been inferred
+	 * from the assignment context (JLS4 15.12.2.8), <code>false</code> otherwise.
+	 *
+	 * This information is available only when bindings are requested when the AST is being built.
+	 *
+	 * @return <code>true</code> if the resolved class type has been inferred
+	 * 	from the assignment context (JLS3 15.12.2.8), <code>false</code> otherwise
+	 * @since 3.7
+	 */
+	public boolean isResolvedTypeInferredFromExpectedType();
+</pre>
+</li>
+</ul>
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340747">340747</a>
+[1.7][compiler] compiler option to warn when diamond can be used, but type args are used instead.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350895">350895</a>
+[1.7][formatter] New option to wrap before/after '|' in multi-catch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350652">350652</a>
+[1.7][assist] Completion issues with multicatch (FUP of 343637)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350095">350095</a>
+The 2000th (0-based) enum constant is null
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347503">347503</a>
+[DOM] ASTParser.setEnvironment() ignores includeRunningVMBootclasspath parameter
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350897">350897</a>
+[1.7][api] ClassInstanceCreation#isResolvedTypeInferredFromExpectedType()
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=351170">351170</a>
+[1.7] ASTRewrite issues in Try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348493">348493</a>
+[1.7] Improve error msg for Diamond operator in 1.5 mode
+
+<a name="v_B66"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - July 5, 2011
+<br>Project org.eclipse.jdt.core v_B66
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B66">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350885">350885</a>
+[Search] The pull up refactoring throws an NPE when pulling up a member that already exists in the superclass
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350611">350611</a>
+[1.7] Inconsistent error msg and error location for illegal diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350579">350579</a>
+[1.7][compiler] VerifyError running example from bug 338402 comment 5
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350767">350767</a>
+[1.7][assist] CCE while invoking assist on a multi-catch block
+
+<a name="v_B65"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - June 30, 2011
+<br>Project org.eclipse.jdt.core v_B65
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B65">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349312">349312</a>
+[1.7][compiler] improved problem messages
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350003">350003</a>
+[1.7] [compiler] AnnotationPolymorphicSignature tag is not being set to invokeExact while compiling MethodHandle source file
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350496">350496</a>
+[1.7] @PolymorphicSignature IMethods are missing the annotation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349314">349314</a>
+[1.7][formatter] Line wrapping for multi-catch arguments
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350039">350039</a>
+[1.7] ASTParser#createASTs(..) doesn't resolve IMethodBinding for @PolymorphicSignature method reference
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349396">349396</a>
+[1.7][formatter] Line wrapping and indentation options for try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350361">350361</a>
+[1.7] Unhandled exception type Exception
+
+<a name="v_B64"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - June 23, 2011
+<br>Project org.eclipse.jdt.core v_B64
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B64">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349488">349488</a>
+[1.7] IMethodBinding#getMethodDeclaration() should return the declaration of @PolymorphicSignature methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349487">349487</a>
+[1.7] IMethodBinding#getJavaElement() returns inexistent element for @PolymorphicSignature methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862">349862</a>
+[1.7] NPE when trying to use UnionType as TryStatement resource
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349864">349864</a>
+[1.7][compiler] Error message considers AutoCloseable as class
+
+<a name="v_B63"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - June 17, 2011
+<br>Project org.eclipse.jdt.core v_B63
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B63">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348956">348956</a>
+[1.7] ITypeBinding#isAssignmentCompatible(ITypeBinding) returns different result
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349312">349312</a>
+[1.7][compiler] improved problem messages
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349008">349008</a>
+[1.7] Ugly formatting for try with resources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=349072">349072</a>
+[1.7] &quot;Cannot infer elided type(s)&quot; sounds too elite
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348705">348705</a>
+[1.7][compiler] Improve error message for unhandled IOException generated due to compiler-generated close()
+
+<a name="v_B62"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7 - June 7, 2011
+<br>Project org.eclipse.jdt.core v_B62
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B62">cvs</a>).
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348050">348050</a>
+[1.7] Error in JDT Core during AST creation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348406">348406</a>
+[1.7] Incorrect error msg on try with resources in 1.5 mode 
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348492">348492</a>
+[1.7] Improve error msg on strings in switch in 1.5 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348491">348491</a>
+[1.7] Rename IProblem.IllegalBinaryLiteral to BinaryLiteralNotBelow17 and IProblem.IllegalUsageOfUnderscore to UnderscoreInLiteralsNotBelow17
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348369">348369</a>
+[1.7] Missing error &quot;No exception of type Exception[] can be thrown&quot;
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=348379">348379</a>
+[1.7][compiler] Null pointer access warning for strings in switch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346415">346415</a>
+[1.7][assist] No proposal inside catch statement from 3rd catch block onwards
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454">346454</a>
+[1.7][content assist]Getting NegativeArraySizeException while trying content assist after diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347600">347600</a>
+[1.7][compiler] Suspect bounds check failure after inference.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347746">347746</a>
+[1.7][compiler] Bounds check failure during method inference
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283353">283353</a>
+[1.5][compiler] Eclipse compiler shows error on javac-valid construct: Bound mismatch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347145">347145</a>
+[1.7][compiler] Bounds check issue with raw types in method inference
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=347426">347426</a>
+[1.7][compiler] ecj behavior differs from javac
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344522">344522</a>
+[1.7] Incorrect source range for ParameterizedType in case of Diamond
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341795">341795</a>
+[1.7][compiler] Cannot assign a generic method with multiple bounds return value to any variable
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159">242159</a>
+[1.7][compiler] type inference with unbounded wildcard in result type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343693">343693</a>
+[1.7] Adjust subclasses of AllocationExpression for &lt;&gt; support
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343637">343637</a>
+[1.7] Already used exception offered again in a Mulicatch block
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345968">345968</a>
+[1.7][compiler] NPE while using diamond for inner class allocation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334313">334313</a>
+[1.5][compiler] Bug in the way eclipse handles overriding of generic abstract method by a non-abstract method
+
 <a name="v_B61"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7 - May 25, 2011 - 3.7.0
+Eclipse SDK 3.7 - June 7, 2011
 <br>Project org.eclipse.jdt.core v_B61
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B61">cvs</a>).
 <h2>What's new in this drop</h2>
@@ -58,7 +366,7 @@
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7RC2 - May 19, 2011 - 3.7.0 RC2
+Eclipse SDK 3.7RC2 - May 19, 2011
 <br>Project org.eclipse.jdt.core v_B60
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B60">cvs</a>).
 <h2>What's new in this drop</h2>
@@ -68,6 +376,18 @@
 Import of User Library with invalid path hoses User Library Dialog -- can not fix
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340181">340181</a>
 Formatter from the command line breaks
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=346029">346029</a>
+[1.7][compiler] Eclipse compiles code rejected by JDK7
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345628">345628</a>
+[1.7] Rename disjunctive type to union type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345559">345559</a>
+[1.7][compiler] Type inference for generic allocation can be avoided for invalid constructor
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342819">342819</a>
+Code rejected by javac with name clash error compiles under eclipse.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334306">334306</a>
+[1.7][compiler] name clash reported in javac 1.7 and not in javac 1.6
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345579">345579</a>
+[1.7][compiler] Weird error message in rethrow site
 
 <a name="v_B59"></a>
 <hr><h1>
@@ -81,6 +401,8 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345569">345569</a>
 FUP of bug 345334: CodeSnippetTest has lot of failures
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345522">345522</a>
+[1.7][compiler] Compilers fails to compute precisely rethrown types
 
 <a name="v_B58"></a>
 <hr><h1>
@@ -94,6 +416,14 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345334">345334</a>
 CodeSnippet's run method is missing @Override annotation
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344824">344824</a>
+[1.7][compiler] Incorrect error range for unreachable catch block error in multi-catch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340486">340486</a>
+[1.7][compiler] Missing error in multi catch scenario
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359">345359</a>
+[1.7][compiler] AIOOB on diamond construct with argument error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=345239">345239</a>
+[1.7][compiler] Compiler should issue better diagnostics for use of &lt;&gt; with anonymous classes
 
 <a name="v_B57"></a>
 <hr><h1>
@@ -109,6 +439,8 @@
 &quot;Content Assist&quot; does not complete normally on certain types
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324987">324987</a>
 [formatter] API compatibility problem with Annotation Newline options
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=344655">344655</a>
+[1.7][compiler] Prohibit use of &lt;&gt; with explicit type arguments to generic constructor
 
 <a name="v_B56"></a>
 <hr><h1>
@@ -123,6 +455,8 @@
 </ul>
 
 <h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=328575">328575</a>
+Inheritance of annotation fails with generic classes
 
 <a name="v_B55"></a>
 <hr><h1>
@@ -163,6 +497,7 @@
 <ul>
 <li>Reverting fix for bug 292087: anonymous class in array member initializer confuses content assist</li>
 </ul>
+
 <h3>Problem Reports Fixed</h3>
 
 <a name="v_B52"></a>
@@ -174,9 +509,11 @@
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B52">cvs</a>).
 <h2>What's new in this drop</h2>
 <ul>
-<li>Only copyright updates have been released.</li>
+<li>Update copyrights</li>
 </ul>
 <h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785">343785</a>
+[1.7] Incorrect line numbers in stack trace with try with resources
 
 <a name="v_B51"></a>
 <hr><h1>
@@ -192,6 +529,10 @@
 Document assumptions about DefaultBindingResolver.newAstToOldAst
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343713">343713</a>
 [compiler] bogus line number in constructor of inner class in 1.5 compliance
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343687">343687</a>
+[1.7] IAE in NumberLiteral#setToken(String) for binary tokens and tokens with underscore
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339478">339478</a>
+[1.7][compiler] support for diamond case
 
 <a name="v_B50"></a>
 <hr><h1>
@@ -205,6 +546,12 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343607">343607</a>
 [APT] Improve output for javax.annotation.processing.Messager problems
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476">343476</a>
+[1.7][assist] propose String variables and fields inside catch expression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087">292087</a>
+anonymous class in array member initializer confuses content assist
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343475">343475</a>
+[1.7] Compiler warning for invalid type inside switch needs to be improved
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342">343342</a>
 [assist] Non constant variables, strings and methods are proposed inside case statements
 
@@ -237,8 +584,6 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337415">337415</a>
 External folders project is not created
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342936">342936</a>
-NPEs and inconsistencies when running jdt.compiler.tool.tests against Java 7
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342455">342455</a>
 AST swallows stars ('*') at end of {@code} and {@literal} Javadoc fragments
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342757">342757</a>
@@ -252,7 +597,7 @@
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7M7 - April 12, 2011
+Eclipse SDK 3.7M7 - April 13, 2011
 <br>Project org.eclipse.jdt.core v_B47
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B47">cvs</a>).
 <h2>What's new in this drop</h2>
@@ -260,6 +605,10 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342300">342300</a>
 [null]Spurious &quot;null pointer access&quot; warning on unboxing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=342416">342416</a>
+[1.7] Signature#createIntersectionTypeSignature(..) should take array of signatures
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340059">340059</a>
+[1.7] IAE when dealing with Signature of disjunctive type
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341759">341759</a>
 NPE in ITypeBinding#getName() for intersection type
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341499">341499</a>
@@ -271,7 +620,7 @@
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7M7 - April 5, 2011
+Eclipse SDK 3.7M7 - April 6, 2011
 <br>Project org.eclipse.jdt.core v_B46
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B46">cvs</a>).
 <h2>What's new in this drop</h2>
@@ -286,14 +635,26 @@
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7M7 - March 29, 2011
+Eclipse SDK 3.7M7 - April 6, 2011
 <br>Project org.eclipse.jdt.core v_B45
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B45">cvs</a>).
 <h2>What's new in this drop</h2>
 
 <h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=200827">200827</a>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338789">338789</a>
+[1.7][assist] No proposal inside a multi catch statement after '|'
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=341333">341333</a>
+[1.7][compiler] DisjunctiveTypeReference#resolveType(..) does not set the value for DisjunctiveTypeReference$resolvedType
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340634">340634</a>
+[1.7][compiler][multicatch] Compiler accepts type variables as catch parameter type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=200827">200827</a>
 [spec] IElementChangedListener should mention where to register
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340626">340626</a>
+[1.7][compiler] Inconsistent source pinpointing in multi-catch blocks
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340513">340513</a>
+[1.7][compiler] Unicode 6.0 characters work at compiler compliance level 1.5 and 1.6
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340445">340445</a>
+[1.7] ASTRewriteAnalyzer and ASTRewriteFlattener need updates
 
 <a name="v_B44"></a>
 <hr><h1>
@@ -307,14 +668,18 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339447">339447</a>
 synchronized access modifier retained on clone() bridge
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340372">340372</a>
+[1.7] NaiveASTFlattener needs to support the new AST nodes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340365">340365</a>
+[1.7] Problems in new APIs (TryStatementWithResources, DisjunctiveType)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340375">340375</a>
+[1.7] Merge TryStatementWithResources into TryStatement
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339891">339891</a>
 NPE when searching for method (with '*' wildcard character)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340022">340022</a>
+[1.7][compiler] Support for precise rethrow
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=340029">340029</a>
 [1.5][compiler] Enum constructor that throws Exception reports a confusing error message
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338011">338011</a>
-COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS wrongly suppresses constructor parameter type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962">337962</a>
-COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS misses reference to field from supertype
 
 <a name="v_B43"></a>
 <hr><h1>
@@ -328,12 +693,22 @@
 <h3>Problem Reports Fixed</h3>
 <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339337">339337</a>
 isLocal() in IType returns true for anonymous types
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339837">339837</a>
+[1.7][compiler] Multicatch syntax not rejected at 1.6-
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337962">337962</a>
+COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS misses reference to field from supertype
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338011">338011</a>
+COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS wrongly suppresses constructor parameter type
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337751">337751</a>
 COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS misses references in conditional expression
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339870">339870</a>
 [1.7] Bad list of subclasses in Statement AST node
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339913">339913</a>
 [compiler] Misleading error message for annotations inside a method body
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=339864">339864</a>
+[1.7] Add recovery in ASTConverter for all new constructs in JLS3 mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402">338402</a>
+[1.7][compiler][enh] Open issues in try with resources implementation
 
 <a name="v_B42"></a>
 <hr><h1>
@@ -415,6 +790,10 @@
 [DOM] code that would definitely cause NPE if executed
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241598">241598</a>
 [API] Constant needed for .classpath
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795">337795</a>
+[1.7][compiler] Missing unchecked warning at varargs method/ctor declaration site
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337802">337802</a>
+[1.7][compiler] Usage of 0x0ffffffff is being reported as out of range.
 
 <a name="v_B38"></a>
 <hr><h1>
@@ -443,11 +822,18 @@
 </pre>
 </li>
 </ul>
+
 <h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783">334783</a>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799">337799</a>
+[1.7][compiler][varargs] Eclipse fails to report error on incorrect SafeVarargs usage
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337738">337738</a>
+[1.7][content assist]Test CompletionParserTest#testEA_1 fails
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783">334783</a>
 [API] Add new API to ease the retrieval of the parameter annotations for an IMethod
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336046">336046</a>
 Source attachment not recovered when importing Projects
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336782">336782</a>
+[1.7][recovery]Extra error tokens with invalid unary operator
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313870">313870</a>
 Wrong warnings on Java.Compiler.Errors/Warnings &quot;Redundant null check&quot;
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=337275">337275</a>
@@ -489,7 +875,7 @@
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7M6 - February 8, 2011
+Eclipse SDK 3.7M6 - February 11, 2011
 <br>Project org.eclipse.jdt.core v_B36
 (<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B36">cvs</a>).
 <h2>What's new in this drop</h2>
@@ -507,6 +893,8 @@
 Bogus potential null pointer access warning (regression; works with 3.6)
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=334377">334377</a>
 [1.5][compiler] Invalid 'type mismatch' error in conditional expression (if-else construct behaves correct)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336322">336322</a>
+[1.7][search]CCE while searching for a type reference in multiple catch parameters
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=335780">335780</a>
 Compiler says a method can be potentially static but this method contains 'this'
 <br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310747">310747</a>
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 7bc9dfe..235b5de 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
@@ -542,7 +542,7 @@
 	Binding[] uninterestingBindings = new Binding[1];
 	int forbbidenBindingsPtr = -1;
 	Binding[] forbbidenBindings = new Binding[1];
-	int forbbidenBindingsFilter;
+	int uninterestingBindingsFilter;     // only set when completing on an exception type
 	
 	ImportBinding[] favoriteReferenceBindings;
 	
@@ -558,6 +558,7 @@
 	int  assistNodeInJavadoc = 0;
 	boolean assistNodeCanBeSingleMemberAnnotation = false;
 	boolean assistNodeIsInsideCase = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
+	boolean assistNodeIsString = false;	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476
 	
 	long targetedElement;
 //{ObjectTeams:
@@ -1278,7 +1279,7 @@
 	
 					int relevance = computeBaseRelevance();
 					relevance += computeRelevanceForResolution();
-					relevance += computeRelevanceForInterestingProposal();
+					relevance += computeRelevanceForInterestingProposal(packageName, fullyQualifiedName);
 					relevance += computeRelevanceForRestrictions(accessibility);
 					relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
 	
@@ -1688,7 +1689,7 @@
 		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd);
 
 		scope = computeForbiddenBindings(astNode, astNodeParent, scope);
-		computeUninterestingBindings(astNodeParent, scope);
+		computeUninterestingBindings(astNode, astNodeParent, scope);
 		if(astNodeParent != null) {
 			if(!isValidParent(astNodeParent, astNode, scope)) return false;
 			computeExpectedTypes(astNodeParent, astNode, scope);
@@ -3718,28 +3719,60 @@
 			addExpectedType(TypeBinding.LONG, scope);
 		} else if(parent instanceof ParameterizedSingleTypeReference) {
 			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
-			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
-			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
-			if(typeVariables != null && typeVariables.length >= length) {
-				int index = length - 1;
-				while(index > -1 && ref.typeArguments[index] != node) index--;
-
-				TypeBinding bound = typeVariables[index].firstBound;
-				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+			TypeBinding expected = null;
+			if (this.parser.enclosingNode instanceof AbstractVariableDeclaration ||
+					this.parser.enclosingNode instanceof ReturnStatement) {
+				// completing inside the diamond
+				if (this.parser.enclosingNode instanceof AbstractVariableDeclaration) {
+					AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) this.parser.enclosingNode;
+					expected = abstractVariableDeclaration.initialization != null ? abstractVariableDeclaration.initialization.expectedType() : null;					
+				} else {
+					ReturnStatement returnStatement = (ReturnStatement) this.parser.enclosingNode;
+					if (returnStatement.expression != null) {
+						expected = returnStatement.expression.expectedType();
+					}
+				}	
+				addExpectedType(expected, scope);
+			} else {
+				TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+				int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
+				if(typeVariables != null && typeVariables.length >= length) {
+					int index = length - 1;
+					while(index > -1 && ref.typeArguments[index] != node) index--;
+	
+					TypeBinding bound = typeVariables[index].firstBound;
+					addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+				}
 			}
 		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
 			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
-			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
 			TypeReference[][] arguments = ref.typeArguments;
-			if(typeVariables != null) {
-				int iLength = arguments == null ? 0 : arguments.length;
-				done: for (int i = 0; i < iLength; i++) {
-					int jLength = arguments[i] == null ? 0 : arguments[i].length;
-					for (int j = 0; j < jLength; j++) {
-						if(arguments[i][j] == node && typeVariables.length > j) {
-							TypeBinding bound = typeVariables[j].firstBound;
-							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
-							break done;
+			TypeBinding expected = null;
+			if (this.parser.enclosingNode instanceof AbstractVariableDeclaration ||
+					this.parser.enclosingNode instanceof ReturnStatement) {
+				// completing inside the diamond
+				if (this.parser.enclosingNode instanceof AbstractVariableDeclaration) {
+					AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) this.parser.enclosingNode;
+					expected = abstractVariableDeclaration.initialization != null ? abstractVariableDeclaration.initialization.expectedType() : null;
+				} else {
+					ReturnStatement returnStatement = (ReturnStatement) this.parser.enclosingNode;
+					if (returnStatement.expression != null) {
+						expected = returnStatement.expression.expectedType();
+					}
+				}
+				addExpectedType(expected, scope);
+			} else {
+				TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+				if(typeVariables != null) {
+					int iLength = arguments == null ? 0 : arguments.length;
+					done: for (int i = 0; i < iLength; i++) {
+						int jLength = arguments[i] == null ? 0 : arguments[i].length;
+						for (int j = 0; j < jLength; j++) {
+							if(arguments[i][j] == node && typeVariables.length > j) {
+								TypeBinding bound = typeVariables[j].firstBound;
+								addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+								break done;
+							}
 						}
 					}
 				}
@@ -3784,19 +3817,43 @@
 			}
 			if (isException) {
 				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
-				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
+				thrownExceptionFinder.processThrownExceptions((TryStatement) parent, (BlockScope)scope);
+				ReferenceBinding[] bindings = thrownExceptionFinder.getThrownUncaughtExceptions();
+				ReferenceBinding[] alreadyCaughtExceptions = thrownExceptionFinder.getAlreadyCaughtExceptions();
+				ReferenceBinding[] discouragedExceptions = thrownExceptionFinder.getDiscouragedExceptions();
 				if (bindings != null && bindings.length > 0) {
 					for (int i = 0; i < bindings.length; i++) {
 						addExpectedType(bindings[i], scope);
 					}
 					this.expectedTypesFilter = SUPERTYPE;
 				}
+				if (alreadyCaughtExceptions != null && alreadyCaughtExceptions.length > 0) {
+					for (int i = 0; i < alreadyCaughtExceptions.length; i++) {
+						addForbiddenBindings(alreadyCaughtExceptions[i]);
+						this.knownTypes.put(CharOperation.concat(alreadyCaughtExceptions[i].qualifiedPackageName(), alreadyCaughtExceptions[i].qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
+					}
+				}
+				if (discouragedExceptions != null && discouragedExceptions.length > 0) {
+					for (int i = 0; i < discouragedExceptions.length; i++) {
+						addUninterestingBindings(discouragedExceptions[i]);
+						// do not insert into known types. We do need these types to come from
+						// searchAllTypes(..) albeit with lower relevance
+					}
+				}
 			}
 		} else if (parent instanceof SwitchStatement) {
 			SwitchStatement switchStatement = (SwitchStatement) parent;
 			this.assistNodeIsInsideCase = assistNodeIsInsideCase(node, parent);
 			if (switchStatement.expression != null &&
 					switchStatement.expression.resolvedType != null) {
+				if (this.assistNodeIsInsideCase &&
+						switchStatement.expression.resolvedType.id == TypeIds.T_JavaLangString &&
+						this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_7) {
+					// set the field to true even though the expected types array will contain String as
+					// expected type to avoid traversing the array in every case later on.
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476
+					this.assistNodeIsString = true;
+				}
 				addExpectedType(switchStatement.expression.resolvedType, scope);
 			}
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=253008, flag boolean as the expected
@@ -3956,7 +4013,6 @@
 	}
 
 	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
-		this.forbbidenBindingsFilter = NONE;
 		if(scope instanceof ClassScope) {
 			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
 			if(typeDeclaration.superclass == astNode) {
@@ -4007,29 +4063,6 @@
 				}
 				return scope.parent;
 			}
-		} else {
-			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
-				boolean isException = false;
-				if (astNode instanceof CompletionOnSingleTypeReference) {
-					isException = ((CompletionOnSingleTypeReference)astNode).isException();
-				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
-					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
-				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
-					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
-				}
-				if (isException) {
-					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
-					int length = catchArguments == null ? 0 : catchArguments.length;
-					for (int i = 0; i < length; i++) {
-						TypeBinding caughtException = catchArguments[i].type.resolvedType;
-						if (caughtException != null) {
-							addForbiddenBindings(caughtException);
-							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
-						}
-					}
-					this.forbbidenBindingsFilter = SUBTYPE;
-				}
-			}
 		}
 //		else if(scope instanceof MethodScope) {
 //			MethodScope methodScope = (MethodScope) scope;
@@ -4236,6 +4269,36 @@
 				if(this.uninterestingBindings[i] == binding) {
 					return 0;
 				}
+				if((this.uninterestingBindingsFilter & SUBTYPE) != 0) {
+					if (binding instanceof TypeBinding &&
+							this.uninterestingBindings[i] instanceof TypeBinding &&
+							((TypeBinding)binding).isCompatibleWith((TypeBinding)this.uninterestingBindings[i])) {
+						return 0;
+					}
+				}
+				if ((this.uninterestingBindingsFilter & SUPERTYPE) != 0) {
+					if (binding instanceof TypeBinding &&
+							this.uninterestingBindings[i] instanceof TypeBinding &&
+							((TypeBinding)this.uninterestingBindings[i]).isCompatibleWith((TypeBinding)binding)) {
+						return 0;
+					}
+				}
+			}
+		}
+		return R_INTERESTING;
+	}
+	
+	private int computeRelevanceForInterestingProposal(char[] givenPkgName, char[] fullTypeName) {
+		for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
+			if (this.uninterestingBindings[i] instanceof TypeBinding) {
+				TypeBinding typeBinding = (TypeBinding) this.uninterestingBindings[i];
+				char[] currPkgName = typeBinding.qualifiedPackageName();
+				if (CharOperation.equals(givenPkgName, currPkgName))	{
+					char[] currTypeName = typeBinding.qualifiedSourceName();
+					if (CharOperation.equals(fullTypeName, currTypeName)) {
+						return 0;
+					}
+				}
 			}
 		}
 		return R_INTERESTING;
@@ -4346,11 +4409,36 @@
 		return argTypes;
 	}
 
-	private void computeUninterestingBindings(ASTNode parent, Scope scope){
+	private void computeUninterestingBindings(ASTNode astNode, ASTNode parent, Scope scope){
+		this.uninterestingBindingsFilter = NONE;
 		if(parent instanceof LocalDeclaration) {
 			addUninterestingBindings(((LocalDeclaration)parent).binding);
 		} else if (parent instanceof FieldDeclaration) {
 			addUninterestingBindings(((FieldDeclaration)parent).binding);
+		} else if (parent instanceof TryStatement) {
+			boolean isException = false;
+			if (astNode instanceof CompletionOnSingleTypeReference) {
+				isException = ((CompletionOnSingleTypeReference)astNode).isException();
+			} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+				isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
+			} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+				isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
+			}
+			if (isException) {
+				this.uninterestingBindingsFilter |= SUBTYPE;
+				// super-types also need to be discouraged if we're in a union type (bug 350652)
+				Argument[] args = ((TryStatement)parent).catchArguments;
+				for (int i = 0; i < args.length; i++) {
+					if (args[i].type instanceof UnionTypeReference) {
+						CompletionNodeDetector detector = new CompletionNodeDetector(astNode, args[i]);
+						if (detector.containsCompletionNode()) {
+							this.uninterestingBindingsFilter |= SUPERTYPE;
+							break;
+						}
+					}
+				}
+				
+			}
 		}
 	}
 
@@ -4869,7 +4957,7 @@
 		
 		int relevance = computeBaseRelevance();
 		relevance += computeRelevanceForResolution();
-		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForInterestingProposal(currentType);
 		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 		
 		if (missingElements != null) {
@@ -5206,7 +5294,22 @@
 		int relevance) {
 
 		// No visibility checks can be performed without the scope & invocationSite
-		MethodBinding[] methods = currentType.availableMethods();
+		MethodBinding[] methods = null;
+		if (currentType instanceof ParameterizedTypeBinding && invocationSite instanceof CompletionOnQualifiedAllocationExpression) {
+			CompletionOnQualifiedAllocationExpression alloc = (CompletionOnQualifiedAllocationExpression) invocationSite;
+			if ((alloc.bits & ASTNode.IsDiamond) != 0) {
+				// inference failed. So don't substitute type arguments. Just return the unsubstituted methods
+				// and let the user decide what to substitute.
+				ParameterizedTypeBinding binding = (ParameterizedTypeBinding) currentType;
+				ReferenceBinding originalGenericType = binding.genericType();
+				if (originalGenericType != null)
+					methods = originalGenericType.methods();
+			} else {
+				methods = currentType.availableMethods();
+			}
+		} else {
+			methods = currentType.availableMethods();
+		}
 		if(methods != null) {
 			int minArgLength = argTypes == null ? 0 : argTypes.length;
 			next : for (int f = methods.length; --f >= 0;) {
@@ -5940,6 +6043,8 @@
 				return;
 			}
 		}
+		
+		if (isForbidden(exceptionType)) return;
 
 		for (int j = typesFound.size; --j >= 0;) {
 			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
@@ -6057,7 +6162,7 @@
 
 		int relevance = computeBaseRelevance();
 		relevance += computeRelevanceForResolution();
-		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForInterestingProposal(exceptionType);
 		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
 		relevance += computeRelevanceForExpectingType(exceptionType);
 		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
@@ -6289,7 +6394,10 @@
 			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342
 			if (this.assistNodeIsInsideCase) {
 				if (field.isFinal() && field.isStatic()) {
-					if (!(field.type instanceof BaseTypeBinding))
+					if (this.assistNodeIsString){
+						if (field.type == null || field.type.id != TypeIds.T_JavaLangString)
+							continue next;
+					} else if (!(field.type instanceof BaseTypeBinding))
 						continue next; 
 				} else {
 					continue next; // non-constants not allowed in case.	
@@ -9926,7 +10034,7 @@
 			if (this.assistNodeIsExtendedType && memberType.isFinal()) continue next;
 			if (this.assistNodeIsInterfaceExcludingAnnotation && memberType.isAnnotationType()) continue next;
 			if(!this.insideQualifiedReference) {
-				if(this.assistNodeIsClass) {
+				if(this.assistNodeIsClass || this.assistNodeIsException) {
 //{ObjectTeams: different determination of class/interface for roles:
 /* orig:
 					if(!memberType.isClass()) continue next;
@@ -9970,7 +10078,7 @@
 
 			int relevance = computeBaseRelevance();
 			relevance += computeRelevanceForResolution();
-			relevance += computeRelevanceForInterestingProposal();
+			relevance += computeRelevanceForInterestingProposal(memberType);
 			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
 			relevance += computeRelevanceForExpectingType(memberType);
 			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
@@ -10537,7 +10645,7 @@
 
 								int relevance = computeBaseRelevance();
 								relevance += computeRelevanceForResolution();
-								relevance += computeRelevanceForInterestingProposal();
+								relevance += computeRelevanceForInterestingProposal(localType);
 								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
 								relevance += computeRelevanceForExpectingType(localType);
 								relevance += computeRelevanceForException(localType.sourceName);
@@ -11028,15 +11136,18 @@
 					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
 				} else if (this.assistNodeIsAnnotation) {
 					if(!sourceType.isAnnotationType()) continue next;
-				} else if (isEmptyPrefix && this.assistNodeIsException) {
-					if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
-						continue next;
-					}
+				} else if (this.assistNodeIsException) {
+					 if (!sourceType.isClass()) continue next;
+					 if (isEmptyPrefix) {
+						 if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
+							 continue next;
+					     }
+					  }
 				}
 
 				int relevance = computeBaseRelevance();
 				relevance += computeRelevanceForResolution();
-				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForInterestingProposal(sourceType);
 				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
 				relevance += computeRelevanceForExpectingType(sourceType);
 				relevance += computeRelevanceForQualification(false);
@@ -11153,7 +11264,7 @@
 					this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
 				}
 				int searchFor = IJavaSearchConstants.TYPE;
-				if(this.assistNodeIsClass) {
+				if(this.assistNodeIsClass || this.assistNodeIsException) {
 					searchFor = IJavaSearchConstants.CLASS;
 				} else if (this.assistNodeIsInterfaceExcludingAnnotation) {
 					searchFor = IJavaSearchConstants.INTERFACE;
@@ -11275,7 +11386,7 @@
 
 				int relevance = computeBaseRelevance();
 				relevance += computeRelevanceForResolution();
-				relevance += computeRelevanceForInterestingProposal();
+				relevance += computeRelevanceForInterestingProposal(sourceType);
 				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
 				relevance += computeRelevanceForExpectingType(sourceType);
 				relevance += computeRelevanceForQualification(false);
@@ -11415,6 +11526,7 @@
 							}
 						}
 					}
+					if(isForbidden(refBinding)) continue next;
 
 					for (int j = 0; j < typesFound.size(); j++) {
 						ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
@@ -11456,7 +11568,7 @@
 
 						int relevance = computeBaseRelevance();
 						relevance += computeRelevanceForResolution();
-						relevance += computeRelevanceForInterestingProposal();
+						relevance += computeRelevanceForInterestingProposal(refBinding);
 						relevance += computeRelevanceForCaseMatching(token, typeName);
 						relevance += computeRelevanceForExpectingType(refBinding);
 						relevance += computeRelevanceForQualification(isQualified);
@@ -11587,7 +11699,7 @@
 							
 							int relevance = computeBaseRelevance();
 							relevance += computeRelevanceForResolution();
-							relevance += computeRelevanceForInterestingProposal();
+							relevance += computeRelevanceForInterestingProposal(typeBinding);
 							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
 							relevance += computeRelevanceForExpectingType(typeBinding);
 							relevance += computeRelevanceForQualification(false);
@@ -11681,7 +11793,7 @@
 
 							if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue;
 							if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue;
-							if(this.assistNodeIsClass) {
+							if(this.assistNodeIsClass || this.assistNodeIsException) {
 								if(!typeBinding.isClass()) continue;
 							} else if(this.assistNodeIsInterface) {
 								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
@@ -11691,7 +11803,7 @@
 
 							int relevance = computeBaseRelevance();
 							relevance += computeRelevanceForResolution();
-							relevance += computeRelevanceForInterestingProposal();
+							relevance += computeRelevanceForInterestingProposal(typeBinding);
 							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
 							relevance += computeRelevanceForExpectingType(typeBinding);
 							relevance += computeRelevanceForQualification(false);
@@ -12216,7 +12328,10 @@
 							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342
 							if (this.assistNodeIsInsideCase) {
 								if (local.isFinal()) {
-									if (!(local.type instanceof BaseTypeBinding))
+									if (this.assistNodeIsString){
+										if (local.type == null || local.type.id != TypeIds.T_JavaLangString)
+											continue next;
+									} else if (!(local.type instanceof BaseTypeBinding))
 										continue next; 
 								} else {
 									continue next; // non-constants not allowed in case.	
@@ -12616,13 +12731,6 @@
 			if(this.forbbidenBindings[i] == binding) {
 				return true;
 			}
-			if((this.forbbidenBindingsFilter & SUBTYPE) != 0) {
-				if (binding instanceof TypeBinding &&
-						this.forbbidenBindings[i] instanceof TypeBinding &&
-						((TypeBinding)binding).isCompatibleWith((TypeBinding)this.forbbidenBindings[i])) {
-					return true;
-				}
-			}
 		}
 		return false;
 	}
@@ -13296,7 +13404,7 @@
 
 		int relevance = computeBaseRelevance();
 		relevance += computeRelevanceForResolution();
-		relevance += computeRelevanceForInterestingProposal();
+		relevance += computeRelevanceForInterestingProposal(packageName, fullyQualifiedName);
 		relevance += computeRelevanceForRestrictions(accessibility);
 		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
 		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
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 7b4e0e8..30620ea 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,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2010 IBM Corporation and others.
+ * Copyright (c) 2004, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Andreas Magnusson <andreas.ch.magnusson@gmail.com>- contribution for bug 151500
@@ -13,6 +13,7 @@
 package org.eclipse.jdt.internal.codeassist;
 
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.core.CompletionContext;
 import org.eclipse.jdt.core.CompletionFlags;
 import org.eclipse.jdt.core.CompletionProposal;
 import org.eclipse.jdt.core.CompletionRequestor;
@@ -1812,4 +1813,32 @@
 		buffer.append('}');
 		return buffer.toString();
 	}
+
+	public boolean canUseDiamond(CompletionContext coreContext) {
+		if (this.getKind() != CONSTRUCTOR_INVOCATION) return false;
+		if (coreContext instanceof InternalCompletionContext) {
+			InternalCompletionContext internalCompletionContext = (InternalCompletionContext) coreContext;
+			if (internalCompletionContext.extendedContext == null) return false;
+			char[] name1 = this.declarationPackageName;
+			char[] name2 = this.declarationTypeName;
+			char[] declarationType = CharOperation.concat(name1, name2, '.');  // fully qualified name
+			// even if the type arguments used in the method have been substituted,
+			// extract the original type arguments only, since thats what we want to compare with the class
+			// type variables (Substitution might have happened when the constructor is coming from another
+			// CU and not the current one).
+			char[] sign = (this.originalSignature != null)? this.originalSignature : getSignature();
+			if (!(sign == null || sign.length < 2)) {
+				sign = Signature.removeCapture(sign);
+			}
+			char[][] types= Signature.getParameterTypes(sign);
+			String[] paramTypeNames= new String[types.length];
+			for (int i= 0; i < types.length; i++) {
+				paramTypeNames[i]= new String(Signature.toCharArray(types[i]));
+			}
+			return internalCompletionContext.extendedContext.canUseDiamond(paramTypeNames,declarationType);
+		}
+		else {
+			return false;
+		}
+	}
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
index 6f62c90..d596d6c 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/InternalExtendedCompletionContext.java
@@ -1,10 +1,10 @@
 /*******************************************************************************
- * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * Copyright (c) 2008, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Technical University Berlin - extended API and implementation
@@ -30,8 +30,12 @@
 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.Initializer;
 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
@@ -899,4 +903,45 @@
 			}
 		}
 	}
+
+	public boolean canUseDiamond(String[] parameterTypes, char[] fullyQualifiedTypeName) {
+		TypeBinding guessedType = null;
+		char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName);
+		Scope scope = this.assistScope;
+		if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return false;
+		// If no LHS or return type expected, then we can safely use diamond
+		char[][] expectedTypekeys= this.completionContext.getExpectedTypesKeys();
+		if (expectedTypekeys == null || expectedTypekeys.length == 0)
+			return true;
+		// Next, find out whether any of the constructor parameters are the same as one of the 
+		// class type variables. If yes, diamond cannot be used.
+		TypeReference ref;
+		if (cn.length == 1) {
+			ref = new SingleTypeReference(cn[0], 0);
+		} else {
+			ref = new QualifiedTypeReference(cn,new long[cn.length]);
+		}
+		switch (scope.kind) {
+			case Scope.METHOD_SCOPE :
+			case Scope.BLOCK_SCOPE :
+				guessedType = ref.resolveType((BlockScope)scope);
+				break;
+			case Scope.CLASS_SCOPE :
+				guessedType = ref.resolveType((ClassScope)scope);
+				break;
+		}
+		if (guessedType != null && guessedType.isValidBinding()) {
+			// the erasure must be used because guessedType can be a RawTypeBinding
+			guessedType = guessedType.erasure();
+			TypeVariableBinding[] typeVars = guessedType.typeVariables();
+			for (int i = 0; i < parameterTypes.length; i++) {
+				for (int j = 0; j < typeVars.length; j++) {
+					if (CharOperation.equals(parameterTypes[i].toCharArray(), typeVars[j].sourceName))
+						return false;
+				}
+			}
+			return true;
+		}
+		return false;
+	}
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
index 89ed4db..3f4004e 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/ThrownExceptionFinder.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2009 IBM Corporation and others.
+ * Copyright (c) 2007, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@
 import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
 import org.eclipse.jdt.internal.compiler.ast.TryStatement;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
@@ -32,16 +33,24 @@
 
 	private SimpleSet thrownExceptions;
 	private Stack exceptionsStack;
+	private SimpleSet caughtExceptions;
+	private SimpleSet discouragedExceptions;
 
-	public ReferenceBinding[] find(TryStatement tryStatement, BlockScope scope) {
+	/**
+	 * Finds the thrown exceptions minus the ones that are already caught in previous catch blocks.
+	 * Exception is already caught even if its super type is being caught. Also computes, separately,
+	 * a list comprising of (a)those exceptions that have been caught already and (b)those exceptions that are thrown
+	 * by the method and whose super type has been caught already. 
+	 * @param tryStatement
+	 * @param scope
+	 */
+	public void processThrownExceptions(TryStatement tryStatement, BlockScope scope) {
 		this.thrownExceptions = new SimpleSet();
 		this.exceptionsStack = new Stack();
+		this.caughtExceptions = new SimpleSet();
+		this.discouragedExceptions = new SimpleSet();
 		tryStatement.traverse(this, scope);
-		removeCaughtExceptions(tryStatement);
-
-		ReferenceBinding[] result = new ReferenceBinding[this.thrownExceptions.elementSize];
-		this.thrownExceptions.asArray(result);
-		return result;
+		removeCaughtExceptions(tryStatement, true /*remove unchecked exceptions this time*/);
 	}
 
 	private void acceptException(ReferenceBinding binding) {
@@ -78,6 +87,42 @@
 		}
 	}
 
+
+	/**
+	 * Returns all the already caught exceptions in catch blocks, found by the call to
+	 * {@link ThrownExceptionFinder#processThrownExceptions(TryStatement, BlockScope)}
+	 * @return Returns an array of those exceptions that have been caught already in previous catch or
+	 * multi-catch blocks of the same try block. (Exceptions caught in inner try-catches are obtained via
+	 * {@link ThrownExceptionFinder#getDiscouragedExceptions()}.
+	 */
+	public ReferenceBinding[] getAlreadyCaughtExceptions() {
+		ReferenceBinding[] allCaughtExceptions = new ReferenceBinding[this.caughtExceptions.elementSize];
+		this.caughtExceptions.asArray(allCaughtExceptions);
+		return allCaughtExceptions;
+	}
+	
+	/**
+	 * Returns all the thrown exceptions minus the ones that are already caught in previous catch blocks
+	 * (of the same try), found by the call to 
+	 * {@link ThrownExceptionFinder#processThrownExceptions(TryStatement, BlockScope)}.
+	 * @return Returns an array of thrown exceptions that are still not caught in any catch block.
+	 */
+	public ReferenceBinding[] getThrownUncaughtExceptions() {
+		ReferenceBinding[] result = new ReferenceBinding[this.thrownExceptions.elementSize];
+		this.thrownExceptions.asArray(result);
+		return result;
+	}
+	
+	/**
+	 * Returns all exceptions that are discouraged to use because (a) they are already caught in some inner try-catch, 
+	 * or (b) their super exception has already been caught.
+	 * @return all discouraged exceptions
+	 */
+	public ReferenceBinding[] getDiscouragedExceptions() {
+		ReferenceBinding[] allDiscouragedExceptions = new ReferenceBinding[this.discouragedExceptions.elementSize];
+		this.discouragedExceptions.asArray(allDiscouragedExceptions);
+		return allDiscouragedExceptions;
+	}
 	public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
 		return visitType(typeDeclaration);
 	}
@@ -100,7 +145,7 @@
 		this.thrownExceptions = exceptionSet;
 		tryStatement.tryBlock.traverse(this, scope);
 
-		removeCaughtExceptions(tryStatement);
+		removeCaughtExceptions(tryStatement, false);
 
 		this.thrownExceptions = (SimpleSet)this.exceptionsStack.pop();
 
@@ -118,15 +163,45 @@
 		}
 		return false;
 	}
-
-	private void removeCaughtExceptions(TryStatement tryStatement) {
+	
+	private void removeCaughtExceptions(TryStatement tryStatement, boolean recordUncheckedCaughtExceptions) {
 		Argument[] catchArguments = tryStatement.catchArguments;
 		int length = catchArguments == null ? 0 : catchArguments.length;
 		for (int i = 0; i < length; i++) {
-			TypeBinding exception = catchArguments[i].type.resolvedType;
-			if (exception != null && exception.isValidBinding()) {
-				removeCaughtException((ReferenceBinding)exception);
-
+			if (catchArguments[i].type instanceof UnionTypeReference) {
+				UnionTypeReference unionTypeReference = (UnionTypeReference) catchArguments[i].type;
+				TypeBinding caughtException;
+				for (int j = 0; j < unionTypeReference.typeReferences.length; j++) {
+					caughtException = unionTypeReference.typeReferences[j].resolvedType;
+					if ((caughtException instanceof ReferenceBinding) && caughtException.isValidBinding()) {	// might be null when its the completion node
+						if (recordUncheckedCaughtExceptions) {
+							// is in outermost try-catch. Remove all caught exceptions, unchecked or checked
+							removeCaughtException((ReferenceBinding)caughtException);
+							this.caughtExceptions.add(caughtException);
+						} else {
+							// is in some inner try-catch. Discourage already caught checked exceptions
+							// from being proposed in an outer catch.
+							if (!caughtException.isUncheckedException(true)) {
+								this.discouragedExceptions.add(caughtException);
+							}
+						}
+					}
+				}
+			} else {
+				TypeBinding exception = catchArguments[i].type.resolvedType;
+				if ((exception instanceof ReferenceBinding) && exception.isValidBinding()) {
+					if (recordUncheckedCaughtExceptions) {
+						// is in outermost try-catch. Remove all caught exceptions, unchecked or checked
+						removeCaughtException((ReferenceBinding)exception);
+						this.caughtExceptions.add(exception);
+					} else {
+						// is in some inner try-catch. Discourage already caught checked exceptions
+						// from being proposed in an outer catch
+						if (!exception.isUncheckedException(true)) {
+							this.discouragedExceptions.add(exception);
+						}
+					}
+				}
 			}
 		}
 	}
@@ -136,8 +211,14 @@
 		for (int i = 0; i < exceptions.length; i++) {
 			ReferenceBinding exception = (ReferenceBinding)exceptions[i];
 			if (exception != null) {
-				if (exception == caughtException || caughtException.isSuperclassOf(exception)) {
+				if (exception == caughtException) {
 					this.thrownExceptions.remove(exception);
+				} else if (caughtException.isSuperclassOf(exception)) {
+					// catching the sub-exception when super has been caught already will give an error
+					// so remove it from thrown list and lower the relevance for cases when it is found
+					// from searchAllTypes(..)
+					this.thrownExceptions.remove(exception);
+					this.discouragedExceptions.add(exception);
 				}
 			}
 		}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
index ad4f663..1bfea9a 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -488,7 +488,7 @@
 						isTypeParam = identifier.length > 0 && identifier[0] == '<';
 						break;
 				}
-				if (identifier != null && identifier.length > 0 && ScannerHelper.isJavaIdentifierPart(identifier[0])) {
+				if (identifier != null && identifier.length > 0 && ScannerHelper.isJavaIdentifierPart(this.complianceLevel, identifier[0])) {
 					name = identifier;
 				}
 				startPosition = (int)(this.identifierPositionStack[0]>>32);
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 52d3077..f159de0 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, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *******************************************************************************/
@@ -39,24 +39,56 @@
 
 public class CompletionOnQualifiedAllocationExpression extends QualifiedAllocationExpression {
 public TypeBinding resolveType(BlockScope scope) {
+	TypeBinding[] argumentTypes = Binding.NO_PARAMETERS;
 	if (this.arguments != null) {
 		int argsLength = this.arguments.length;
-		for (int a = argsLength; --a >= 0;)
-			this.arguments[a].resolveType(scope);
+		int length = this.arguments.length;
+		argumentTypes = new TypeBinding[length];
+		for (int a = argsLength; --a >= 0;) {
+			argumentTypes[a] = this.arguments[a].resolveType(scope);
+		}
 	}
-
+	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
 	if (this.enclosingInstance != null) {
 		TypeBinding enclosingType = this.enclosingInstance.resolveType(scope);
+		if (enclosingType == null) {
+			// try to propose something even if enclosing type cannot be resolved.
+			// Eg.: new Test<>().new Test<>(#cursor#
+			if (this.enclosingInstance instanceof AllocationExpression) {
+				TypeReference enclosingInstanceType = ((AllocationExpression) this.enclosingInstance).type;
+				if (enclosingInstanceType != null) {
+					enclosingType = enclosingInstanceType.resolvedType;
+				}
+			}
+		}
 		if (enclosingType == null || !(enclosingType instanceof ReferenceBinding)) {
 			throw new CompletionNodeFound();
 		}
 		this.resolvedType = ((SingleTypeReference) this.type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingType);
+		if (isDiamond && (this.resolvedType instanceof ParameterizedTypeBinding)) {
+			TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+			if (inferredTypes != null) {
+				this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+			} else {
+				// inference failed. Resolved type will be of the form Test<>
+				this.bits |= ASTNode.IsDiamond;
+			}
+	 	}
 		if (!(this.resolvedType instanceof ReferenceBinding))
 			throw new CompletionNodeFound(); // no need to continue if its an array or base type
 		if (this.resolvedType.isInterface()) // handle the anonymous class definition case
 			this.resolvedType = scope.getJavaLangObject();
 	} else {
-		this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+	 	this.resolvedType = this.type.resolveType(scope, true /* check bounds*/);
+	 	if (isDiamond && (this.resolvedType instanceof ParameterizedTypeBinding)) {
+			TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+			if (inferredTypes != null) {
+				this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+			} else {
+				// inference failed. Resolved type will be of the form Test<>
+				this.bits |= ASTNode.IsDiamond;
+			}
+	 	}
 		if (!(this.resolvedType instanceof ReferenceBinding))
 			throw new CompletionNodeFound(); // no need to continue if its an array or base type
 	}
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 a4caabc..7c6c9c1 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: CompletionParser.java 23404 2010-02-03 14:10:22Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
@@ -1204,8 +1203,39 @@
 						}
 						if(this.currentElement instanceof RecoveredType) {
 							this.currentElement = this.currentElement.add(new CompletionOnFieldType(ref, false), 0);
-						} else {
-							this.currentElement = this.currentElement.add(ref, 0);
+						} else {							
+							
+							if (prevKind == K_BETWEEN_NEW_AND_LEFT_BRACKET) {
+								
+								AllocationExpression exp;
+								if (this.expressionPtr > -1 && this.expressionStack[this.expressionPtr] instanceof AllocationExpression) {
+									exp = new QualifiedAllocationExpression();
+									exp.type = ref;
+									((QualifiedAllocationExpression)exp).enclosingInstance = this.expressionStack[this.expressionPtr];
+								} else {
+									exp = new AllocationExpression();
+									exp.type = ref;
+								}
+								if (isInsideReturn()) {
+									ReturnStatement returnStatement = new ReturnStatement(exp, exp.sourceStart, exp.sourceEnd);
+									this.enclosingNode = returnStatement;
+									this.currentElement  = this.currentElement.add(returnStatement,0);
+								} else if (this.currentElement instanceof RecoveredLocalVariable) {
+									if (((RecoveredLocalVariable)this.currentElement).localDeclaration.initialization == null) {
+										this.enclosingNode = ((RecoveredLocalVariable) this.currentElement).localDeclaration;
+										this.currentElement = this.currentElement.add(exp, 0);
+									}
+								} else if (this.currentElement instanceof RecoveredField) {
+									if (((RecoveredField) this.currentElement).fieldDeclaration.initialization == null) {
+										this.enclosingNode = ((RecoveredField) this.currentElement).fieldDeclaration;
+										this.currentElement = this.currentElement.add(exp, 0);
+									}
+								} else {
+									this.currentElement = this.currentElement.add(ref, 0);
+								}
+							} else {
+								this.currentElement = this.currentElement.add(ref, 0);
+							}
 						}
 					} else if (this.currentElement.enclosingMethod() != null &&
 							this.currentElement.enclosingMethod().methodDeclaration.isConstructor()) {
@@ -1217,15 +1247,15 @@
 	}
 }
 private void buildMoreTryStatementCompletionContext(TypeReference exceptionRef) {
-	if (this.astLengthPtr > -1 &&
-			this.astPtr > 1 &&
-			this.astStack[this.astPtr] instanceof Block &&
-			this.astStack[this.astPtr - 1] instanceof Argument) {
+	if (this.astLengthPtr > 0 &&
+			this.astPtr > 2 &&
+			this.astStack[this.astPtr -1] instanceof Block &&
+			this.astStack[this.astPtr - 2] instanceof Argument) {
 		TryStatement tryStatement = new TryStatement();
 
-		int newAstPtr = this.astPtr;
+		int newAstPtr = this.astPtr - 1;
 
-		int length = this.astLengthStack[this.astLengthPtr];
+		int length = this.astLengthStack[this.astLengthPtr - 1];
 		Block[] bks = (tryStatement.catchBlocks = new Block[length + 1]);
 		Argument[] args = (tryStatement.catchArguments = new Argument[length + 1]);
 		if (length != 0) {
@@ -1237,7 +1267,12 @@
 		}
 
 		bks[bks.length - 1] = new Block(0);
-		args[args.length - 1] = new Argument(FAKE_ARGUMENT_NAME,0,exceptionRef,0);
+		if (this.astStack[this.astPtr] instanceof UnionTypeReference) {
+			UnionTypeReference unionTypeReference = (UnionTypeReference) this.astStack[this.astPtr];
+			args[args.length - 1] = new Argument(FAKE_ARGUMENT_NAME,0,unionTypeReference,0);
+		} else {
+			args[args.length - 1] = new Argument(FAKE_ARGUMENT_NAME,0,exceptionRef,0);
+		}
 
 		tryStatement.tryBlock = (Block) this.astStack[newAstPtr--];
 
@@ -1245,17 +1280,22 @@
 
 		this.currentElement.add(tryStatement, 0);
 	} else if (this.astLengthPtr > -1 &&
-			this.astPtr > -1 &&
-			this.astStack[this.astPtr] instanceof Block) {
+			this.astPtr > 0 &&
+			this.astStack[this.astPtr - 1] instanceof Block) {
 		TryStatement tryStatement = new TryStatement();
 
-		int newAstPtr = this.astPtr;
+		int newAstPtr = this.astPtr - 1;
 
 		Block[] bks = (tryStatement.catchBlocks = new Block[1]);
 		Argument[] args = (tryStatement.catchArguments = new Argument[1]);
 
 		bks[0] = new Block(0);
-		args[0] = new Argument(FAKE_ARGUMENT_NAME,0,exceptionRef,0);
+		if (this.astStack[this.astPtr] instanceof UnionTypeReference) {
+			UnionTypeReference unionTypeReference = (UnionTypeReference) this.astStack[this.astPtr];
+			args[0] = new Argument(FAKE_ARGUMENT_NAME,0,unionTypeReference,0);
+		} else {
+			args[0] = new Argument(FAKE_ARGUMENT_NAME,0,exceptionRef,0);
+		}
 
 		tryStatement.tryBlock = (Block) this.astStack[newAstPtr--];
 
@@ -1286,23 +1326,6 @@
 	}
 }
 /**
- * Checks if the completion is on the exception type of a catch clause.
- * Returns whether we found a completion node.
- */
-private boolean checkCatchClause() {
-	if ((topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN) && this.identifierPtr > -1) {
-		// NB: if the cursor is on the variable, then it has been reduced (so identifierPtr is -1),
-		//     thus this can only be a completion on the type of the catch clause
-		pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
-		this.assistNode = getTypeReference(0);
-		popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
-		this.lastCheckPoint = this.assistNode.sourceEnd + 1;
-		this.isOrphanCompletionNode = true;
-		return true;
-	}
-	return false;
-}
-/**
  * Checks if the completion is on the type following a 'new'.
  * Returns whether we found a completion node.
  */
@@ -2289,7 +2312,6 @@
 	if (this.indexOfAssistIdentifier() < 0) return;
 
 	if (checkClassInstanceCreation()) return;
-	if (checkCatchClause()) return;
 	if (checkMemberAccess()) return;
 	if (checkClassLiteralAccess()) return;
 	if (checkInstanceofKeyword()) return;
@@ -2414,6 +2436,50 @@
 	popElement(K_CAST_STATEMENT);
 	super.consumeCastExpressionLL1();
 }
+protected void consumeCatchFormalParameter() {
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeCatchFormalParameter();
+		if (this.pendingAnnotation != null) {
+			this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
+			this.pendingAnnotation = null;
+		}
+	} else {
+		this.identifierLengthPtr--;
+		char[] identifierName = this.identifierStack[this.identifierPtr];
+		long namePositions = this.identifierPositionStack[this.identifierPtr--];
+		this.intPtr--; // dimension from the variabledeclaratorid
+		TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+		this.intPtr -= 2;
+		CompletionOnArgumentName arg =
+			new CompletionOnArgumentName(
+				identifierName,
+				namePositions,
+				type,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+		arg.bits &= ~ASTNode.IsArgument;
+		// consume annotations
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				arg.annotations = new Annotation[length],
+				0,
+				length);
+		}
+
+		arg.isCatchArgument = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN;
+		pushOnAstStack(arg);
+
+		this.assistNode = arg;
+		this.lastCheckPoint = (int) namePositions;
+		this.isOrphanCompletionNode = true;
+
+		/* if incomplete method header, listLength counter will not have been reset,
+			indicating that some arguments are available on the stack */
+		this.listLength++;
+	}
+}
 protected void consumeClassBodyDeclaration() {
 	popElement(K_BLOCK_DELIMITER);
 	super.consumeClassBodyDeclaration();
@@ -2905,63 +2971,13 @@
 		this.listLength++;
 	}
 }
-protected void consumeCatchFormalParameter(boolean isVarArgs) {
-	if (this.indexOfAssistIdentifier() < 0) {
-		super.consumeCatchFormalParameter(isVarArgs);
-		if (this.pendingAnnotation != null) {
-			this.pendingAnnotation.potentialAnnotatedNode = this.astStack[this.astPtr];
-			this.pendingAnnotation = null;
-		}
-	} else {
-
-		this.identifierLengthPtr--;
-		char[] identifierName = this.identifierStack[this.identifierPtr];
-		long namePositions = this.identifierPositionStack[this.identifierPtr--];
-		int extendedDimensions = this.intStack[this.intPtr--];
-		int endOfEllipsis = 0;
-		if (isVarArgs) {
-			endOfEllipsis = this.intStack[this.intPtr--];
-		}
-		int firstDimensions = this.intStack[this.intPtr--];
-		final int typeDimensions = firstDimensions + extendedDimensions;
-		TypeReference type = getTypeReference(typeDimensions);
-		if (isVarArgs) {
-			type = copyDims(type, typeDimensions + 1);
-			if (extendedDimensions == 0) {
-				type.sourceEnd = endOfEllipsis;
-			}
-			type.bits |= ASTNode.IsVarArgs; // set isVarArgs
-		}
-		this.intPtr -= 2;
-		CompletionOnArgumentName arg =
-			new CompletionOnArgumentName(
-				identifierName,
-				namePositions,
-				type,
-				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
-		arg.bits &= ~ASTNode.IsArgument;
-		// consume annotations
-		int length;
-		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
-			System.arraycopy(
-				this.expressionStack,
-				(this.expressionPtr -= length) + 1,
-				arg.annotations = new Annotation[length],
-				0,
-				length);
-		}
-
-		arg.isCatchArgument = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN;
-		pushOnAstStack(arg);
-
-		this.assistNode = arg;
-		this.lastCheckPoint = (int) namePositions;
-		this.isOrphanCompletionNode = true;
-
-		/* if incomplete method header, listLength counter will not have been reset,
-			indicating that some arguments are available on the stack */
-		this.listLength++;
-	}
+protected void consumeGenericTypeWithDiamond() {
+	super.consumeGenericTypeWithDiamond();
+	// we need to pop the <> of the diamond from the stack.
+	// This is not required in usual case when the type argument isn't elided
+	// since the < and > get popped while parsing the type argument. 
+	popElement(K_BINARY_OPERATOR); // pop >
+	popElement(K_BINARY_OPERATOR); // pop <
 }
 protected void consumeStatementFor() {
 	super.consumeStatementFor();
@@ -4082,7 +4098,9 @@
 				pushOnElementStack(K_BINARY_OPERATOR, XOR);
 				break;
 			case TokenNameOR:
-				pushOnElementStack(K_BINARY_OPERATOR, OR);
+				// Don't push the OR operator used for union types in a catch declaration
+				if (topKnownElementKind(COMPLETION_PARSER) != K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+					pushOnElementStack(K_BINARY_OPERATOR, OR);
 				break;
 			case TokenNameAND_AND:
 				pushOnElementStack(K_BINARY_OPERATOR, AND_AND);
@@ -4355,6 +4373,16 @@
 	}
 	popElement(K_EXTENDS_KEYWORD);
 }
+protected void consumeUnionType() {
+	pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
+	super.consumeUnionType();
+	popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+}
+protected void consumeUnionTypeAsClassType() {
+	pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
+	super.consumeUnionTypeAsClassType();
+	popElement(K_NEXT_TYPEREF_IS_EXCEPTION);
+}
 protected void consumeWildcard() {
 	super.consumeWildcard();
 	if (assistIdentifier() == null && this.currentToken == TokenNameIdentifier) { // Test below copied from CompletionScanner.getCurrentIdentifierSource()
@@ -4480,6 +4508,8 @@
 public TypeReference createQualifiedAssistTypeReference(char[][] previousIdentifiers, char[] assistName, long[] positions){
 	switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
 		case K_NEXT_TYPEREF_IS_EXCEPTION :
+			if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+				this.isOrphanCompletionNode = true;
 			return new CompletionOnQualifiedTypeReference(
 					previousIdentifiers,
 					assistName,
@@ -4516,6 +4546,8 @@
 	} else {
 		switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
 			case K_NEXT_TYPEREF_IS_EXCEPTION :
+				if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+					this.isOrphanCompletionNode = true;
 				return new CompletionOnParameterizedQualifiedTypeReference(
 					previousIdentifiers,
 					typeArguments,
@@ -4679,6 +4711,8 @@
 public TypeReference createSingleAssistTypeReference(char[] assistName, long position) {
 	switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
 		case K_NEXT_TYPEREF_IS_EXCEPTION :
+			if (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER, 1) == K_BETWEEN_CATCH_AND_RIGHT_PAREN)
+				this.isOrphanCompletionNode = true;
 			return new CompletionOnSingleTypeReference(assistName, position, CompletionOnSingleTypeReference.K_EXCEPTION) ;
 		case K_NEXT_TYPEREF_IS_CLASS :
 			return new CompletionOnSingleTypeReference(assistName, position, CompletionOnSingleTypeReference.K_CLASS);
@@ -4783,7 +4817,10 @@
 
 protected TypeReference getTypeReferenceForGenericType(int dim,	int identifierLength, int numberOfIdentifiers) {
 	TypeReference ref = super.getTypeReferenceForGenericType(dim, identifierLength, numberOfIdentifiers);
-
+	// in completion case we might have encountered the assist node before really parsing
+	// the complete class instance creation, and so a separate check for diamond is needed here.
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=346454
+	checkForDiamond(ref);
 	if(this.assistNode != null) {
 		if (identifierLength == 1 && numberOfIdentifiers == 1) {
 			ParameterizedSingleTypeReference singleRef = (ParameterizedSingleTypeReference) ref;
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 4b8103f..c4d1f9a 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -170,7 +170,7 @@
 					&& (this.completionIdentifier == null)
 					&& (whiteStart <= this.cursorLocation+1)
 					&& (this.cursorLocation < this.startPosition)
-					&& !ScannerHelper.isJavaIdentifierStart(this.currentCharacter)){
+					&& !ScannerHelper.isJavaIdentifierStart(this.complianceLevel, this.currentCharacter)){
 					this.currentPosition = this.startPosition; // for next token read
 					return TokenNameIdentifier;
 				}
@@ -850,7 +850,7 @@
 							// illegal low surrogate
 							throw new InvalidInputException(INVALID_LOW_SURROGATE);
 						}
-						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(c, low);
+						isJavaIdStart = ScannerHelper.isJavaIdentifierStart(this.complianceLevel, c, low);
 					}
 					else if (c >= LOW_SURROGATE_MIN_VALUE && c <= LOW_SURROGATE_MAX_VALUE) {
 						if (this.complianceLevel < ClassFileConstants.JDK1_5) {
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 ade6cb7..86f4c7a 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: AssistParser.java 23404 2010-02-03 14:10:22Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
@@ -1039,9 +1038,14 @@
 	/* no need to take action if not inside completed identifiers */
 	if (/*(indexOfAssistIdentifier()) < 0 ||*/ (identifierLength == 1 && numberOfIdentifiers == 1)) {
 		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
-		TypeReference[] typeArguments = new TypeReference[currentTypeArgumentsLength];
-		this.genericsPtr -= currentTypeArgumentsLength;
-		System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments, 0, currentTypeArgumentsLength);
+		TypeReference[] typeArguments;
+		if (currentTypeArgumentsLength > -1) {
+			typeArguments = new TypeReference[currentTypeArgumentsLength];
+			this.genericsPtr -= currentTypeArgumentsLength;
+			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments, 0, currentTypeArgumentsLength);
+		} else {
+			typeArguments = TypeReference.NO_TYPE_ARGUMENTS;
+		}
 		long[] positions = new long[identifierLength];
 		System.arraycopy(
 			this.identifierPositionStack,
@@ -1069,7 +1073,7 @@
 	int currentIdentifiersLength = identifierLength;
 	while (index > 0) {
 		int currentTypeArgumentsLength = this.genericsLengthStack[this.genericsLengthPtr--];
-		if (currentTypeArgumentsLength != 0) {
+		if (currentTypeArgumentsLength > 0) {
 			this.genericsPtr -= currentTypeArgumentsLength;
 			System.arraycopy(this.genericsStack, this.genericsPtr + 1, typeArguments[index - 1] = new TypeReference[currentTypeArgumentsLength], 0, currentTypeArgumentsLength);
 		}
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 8280ef4..a2a683a 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -238,6 +238,7 @@
 		char [] oldIdent = assistIdentifier();
 		setAssistIdentifier(null);
 		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
 
 		setAssistIdentifier(oldIdent);
 
@@ -306,6 +307,61 @@
 	popElement(K_CAST_STATEMENT);
 	super.consumeCastExpressionWithQualifiedGenericsArray();
 }
+protected void consumeCatchFormalParameter() {
+	if (this.indexOfAssistIdentifier() < 0) {
+		super.consumeCatchFormalParameter();
+		if((!this.diet || this.dietInt != 0) && this.astPtr > -1) {
+			Argument argument = (Argument) this.astStack[this.astPtr];
+			if(argument.type == this.assistNode) {
+				this.isOrphanCompletionNode = true;
+				this.restartRecovery	= true;	// force to restart in recovery mode
+				this.lastIgnoredToken = -1;
+			}
+		}
+	} else {
+		this.identifierLengthPtr--;
+		char[] identifierName = this.identifierStack[this.identifierPtr];
+		long namePositions = this.identifierPositionStack[this.identifierPtr--];
+		this.intPtr--; // dimension from the variabledeclaratorid
+		TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+		int modifierPositions = this.intStack[this.intPtr--];
+		this.intPtr--;
+		Argument arg =
+			new SelectionOnArgumentName(
+				identifierName,
+				namePositions,
+				type,
+				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+		arg.bits &= ~ASTNode.IsArgument;
+		arg.declarationSourceStart = modifierPositions;
+
+		// consume annotations
+		int length;
+		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+			System.arraycopy(
+				this.expressionStack,
+				(this.expressionPtr -= length) + 1,
+				arg.annotations = new Annotation[length],
+				0,
+				length);
+		}
+
+		pushOnAstStack(arg);
+
+		this.assistNode = arg;
+		this.lastCheckPoint = (int) namePositions;
+		this.isOrphanCompletionNode = true;
+
+		if (!this.diet){
+			this.restartRecovery	= true;	// force to restart in recovery mode
+			this.lastIgnoredToken = -1;
+		}
+
+		/* if incomplete method header, listLength counter will not have been reset,
+			indicating that some arguments are available on the stack */
+		this.listLength++;
+	}
+}
 protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
 	// ClassInstanceCreationExpression ::= Primary '.' 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
 	// ClassInstanceCreationExpression ::= ClassInstanceCreationExpressionName 'new' TypeArguments SimpleName '(' ArgumentListopt ')' ClassBodyopt
@@ -339,6 +395,7 @@
 		char [] oldIdent = assistIdentifier();
 		setAssistIdentifier(null);
 		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
 
 		setAssistIdentifier(oldIdent);
 
@@ -402,6 +459,7 @@
 		char [] oldIdent = assistIdentifier();
 		setAssistIdentifier(null);
 		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
 
 		setAssistIdentifier(oldIdent);
 
@@ -624,79 +682,6 @@
 		this.listLength++;
 	}
 }
-protected void consumeCatchFormalParameter(boolean isVarArgs) {
-	if (this.indexOfAssistIdentifier() < 0) {
-		super.consumeCatchFormalParameter(isVarArgs);
-		if((!this.diet || this.dietInt != 0) && this.astPtr > -1) {
-			Argument argument = (Argument) this.astStack[this.astPtr];
-//{ObjectTeams: consider lifting type
-/* orig:
-			if(argument.type == this.assistNode) {
-  :giro */
-			if (hasAssistNode(argument.type)) {
-// SH}
-				this.isOrphanCompletionNode = true;
-				this.restartRecovery	= true;	// force to restart in recovery mode
-				this.lastIgnoredToken = -1;
-			}
-		}
-	} else {
-		this.identifierLengthPtr--;
-		char[] identifierName = this.identifierStack[this.identifierPtr];
-		long namePositions = this.identifierPositionStack[this.identifierPtr--];
-		int extendedDimensions = this.intStack[this.intPtr--];
-		int endOfEllipsis = 0;
-		if (isVarArgs) {
-			endOfEllipsis = this.intStack[this.intPtr--];
-		}
-		int firstDimensions = this.intStack[this.intPtr--];
-		final int typeDimensions = firstDimensions + extendedDimensions;
-		TypeReference type = getTypeReference(typeDimensions);
-		if (isVarArgs) {
-			type = copyDims(type, typeDimensions + 1);
-			if (extendedDimensions == 0) {
-				type.sourceEnd = endOfEllipsis;
-			}
-			type.bits |= ASTNode.IsVarArgs; // set isVarArgs
-		}
-		int modifierPositions = this.intStack[this.intPtr--];
-		this.intPtr--;
-		Argument arg =
-			new SelectionOnArgumentName(
-				identifierName,
-				namePositions,
-				type,
-				this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
-		arg.bits &= ~ASTNode.IsArgument;
-		arg.declarationSourceStart = modifierPositions;
-
-		// consume annotations
-		int length;
-		if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
-			System.arraycopy(
-				this.expressionStack,
-				(this.expressionPtr -= length) + 1,
-				arg.annotations = new Annotation[length],
-				0,
-				length);
-		}
-
-		pushOnAstStack(arg);
-
-		this.assistNode = arg;
-		this.lastCheckPoint = (int) namePositions;
-		this.isOrphanCompletionNode = true;
-
-		if (!this.diet){
-			this.restartRecovery	= true;	// force to restart in recovery mode
-			this.lastIgnoredToken = -1;
-		}
-
-		/* if incomplete method header, listLength counter will not have been reset,
-			indicating that some arguments are available on the stack */
-		this.listLength++;
-	}
-}
 //{ObjectTeams: is type equal to assistNode or is a lifting type containing assistNode?
 private boolean hasAssistNode(TypeReference type) {
 	if (type == this.assistNode)
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 b614be1..141859a 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Luiz-Otavio Zorzella <zorzella at gmail dot com> - Improve CamelCase algorithm
@@ -755,6 +755,35 @@
 	return length1 - length2;
 }
 /**
+ * Compares the two char arrays lexicographically between the given start and end positions.
+ *
+ * Returns a negative integer if array1 lexicographically precedes the array2,
+ * a positive integer if this array1 lexicographically follows the array2, or
+ * zero if both arrays are equal.
+ * <p>The comparison is done between start and end positions.</p>
+ *
+ * @param array1 the first given array
+ * @param array2 the second given array
+ * @param start the starting position to compare (inclusive)
+ * @param end the ending position to compare (exclusive)
+ * 
+ * @return the returned value of the comparison between array1 and array2
+ * @throws NullPointerException if one of the arrays is null
+ * @since 3.7.1
+ */
+public static final int compareTo(char[] array1, char[] array2, int start, int end) {
+	int length1 = array1.length;
+	int length2 = array2.length;
+	int min = Math.min(length1, length2);
+	min = Math.min(min, end);
+	for (int i = start; i < min; i++) {
+		if (array1[i] != array2[i]) {
+			return array1[i] - array2[i];
+		}
+	}
+	return length1 - length2;
+}
+/**
  * Compares the contents of the two arrays array and prefix. Returns
  * <ul>
  * <li>zero if the array starts with the prefix contents</li>
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 aa6a2ff..81ab7b6 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
@@ -605,6 +605,16 @@
 	int InvalidHighSurrogate = Syntax + Internal + 264;
 	/** @since 3.2 */
 	int UnnecessaryNLSTag = Internal + 265;
+	/** @since 3.7.1 */
+	int InvalidBinary = Syntax + Internal + 266;
+	/** @since 3.7.1 */
+	int BinaryLiteralNotBelow17 = Syntax + Internal + 267;
+	/** @since 3.7.1 */
+	int IllegalUnderscorePosition = Syntax + Internal + 268;
+	/** @since 3.7.1 */
+	int UnderscoresInLiteralsNotBelow17 = Syntax + Internal + 269;
+	/** @since 3.7.1 */
+	int IllegalHexaLiteral = Syntax + Internal + 270;
 
 	// type related problems
 	/** @since 3.1 */
@@ -1145,6 +1155,9 @@
 	/** @since 3.6*/
 	int InvalidTypeForCollectionTarget14 = Internal + 582;
 
+	/** @since 3.7.1 */
+	int DuplicateInheritedMethods = MethodRelated + 583;
+	
 	/**
 	 * 1.5 Syntax errors (when source level < 1.5)
 	 */
@@ -1322,7 +1335,12 @@
 	int ConstructorVarargsArgumentNeedCast = ConstructorRelated + 802;
 	/** @since 3.1 */
 	int VarargsConflict = MethodRelated + 803;
-
+	/** @since 3.7.1 */
+	int SafeVarargsOnFixedArityMethod = MethodRelated + 804;
+	/** @since 3.7.1 */
+	int SafeVarargsOnNonFinalInstanceMethod = MethodRelated + 805;
+	/** @since 3.7.1 */
+	int PotentialHeapPollutionFromVararg = MethodRelated + 806;
 	/**
 	 * Javadoc Generic
 	 */
@@ -1348,6 +1366,39 @@
 	int JavadocTypeArgumentsForRawGenericConstructor = Javadoc + Internal + 859;
 
 	/**
+	 * Java 7 errors
+	 */
+	/** @since 3.7.1 */
+	int AssignmentToMultiCatchParameter = Internal + 870;
+	/** @since 3.7.1 */
+	int ResourceHasToImplementAutoCloseable = TypeRelated + 871;
+	/** @since 3.7.1 */
+	int AssignmentToResource = Internal + 872;
+	/** @since 3.7.1 */
+	int InvalidUnionTypeReferenceSequence = Internal + TypeRelated + 873; 
+	/** @since 3.7.1 */
+	int AutoManagedResourceNotBelow17 = Syntax + Internal + 874;
+	/** @since 3.7.1 */
+	int MultiCatchNotBelow17 =  Syntax + Internal + 875;
+	/** @since 3.7.1 */
+	int PolymorphicMethodNotBelow17 = MethodRelated + 876;
+	/** @since 3.7.1 */
+	int IncorrectSwitchType17 = TypeRelated + 877;
+	/** @since 3.7.1 */
+	int CannotInferElidedTypes = TypeRelated + 878;
+	/** @since 3.7.1 */
+	int CannotUseDiamondWithExplicitTypeArguments = TypeRelated + 879;
+	/** @since 3.7.1 */
+	int CannotUseDiamondWithAnonymousClasses = TypeRelated + 880;
+	/** @since 3.7.1 */
+	int SwitchOnStringsNotBelow17 = TypeRelated + 881;	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=348492
+	/** @since 3.7.1 */
+	int UnhandledExceptionOnAutoClose =  TypeRelated + 882;
+	/** @since 3.7.1 */
+	int DiamondNotBelow17 =  TypeRelated + 883;
+	/** @since 3.7.1 */
+	int RedundantSpecificationOfTypeArguments = TypeRelated + 884;
+	/**
 	 * External problems -- These are problems defined by other plugins
 	 */
 
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 07f130c..3f03b6e 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, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -462,6 +462,16 @@
 	public void endVisit(UnaryExpression unaryExpression, BlockScope scope) {
 		// do nothing by default
 	}
+	public void endVisit(
+			UnionTypeReference unionTypeReference,
+			BlockScope scope) {
+		// do nothing by default
+	}
+	public void endVisit(
+			UnionTypeReference unionTypeReference,
+			ClassScope scope) {
+		// do nothing by default
+	}
 	public void endVisit(WhileStatement whileStatement, BlockScope scope) {
 		// do nothing by default
 	}
@@ -930,6 +940,16 @@
 	public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
 		return true; // do nothing by default, keep traversing
 	}
+	public boolean visit(
+			UnionTypeReference unionTypeReference,
+			BlockScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
+	public boolean visit(
+			UnionTypeReference unionTypeReference,
+			ClassScope scope) {
+		return true; // do nothing by default, keep traversing
+	}
 	public boolean visit(WhileStatement whileStatement, BlockScope scope) {
 		return true; // do nothing by default, keep traversing
 	}
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 022a714..ae739c5 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
@@ -1198,7 +1198,7 @@
 		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
 		int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
 		for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
-			exceptionHandlersCount += this.codeStream.exceptionLabels[i].count / 2;
+			exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
 		}
 		int exSize = exceptionHandlersCount * 8 + 2;
 		if (exSize + localContentsOffset >= this.contents.length) {
@@ -1211,7 +1211,7 @@
 		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
 			ExceptionLabel exceptionLabel = exceptionLabels[i];
 			if (exceptionLabel != null) {
-				int iRange = 0, maxRange = exceptionLabel.count;
+				int iRange = 0, maxRange = exceptionLabel.getCount();
 				if ((maxRange & 1) != 0) {
 					this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
 							Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
@@ -1344,7 +1344,7 @@
 		ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
 		int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
 		for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
-			exceptionHandlersCount += this.codeStream.exceptionLabels[i].count / 2;
+			exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
 		}
 		int exSize = exceptionHandlersCount * 8 + 2;
 		if (exSize + localContentsOffset >= this.contents.length) {
@@ -1357,7 +1357,7 @@
 		for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
 			ExceptionLabel exceptionLabel = exceptionLabels[i];
 			if (exceptionLabel != null) {
-				int iRange = 0, maxRange = exceptionLabel.count;
+				int iRange = 0, maxRange = exceptionLabel.getCount();
 				if ((maxRange & 1) != 0) {
 					this.codeStream.methodDeclaration.scope.problemReporter().abortDueToInternalError(
 							Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
@@ -1779,7 +1779,7 @@
 			ExceptionLabel[] exceptionLabels = this.codeStream.exceptionLabels;
 			int exceptionHandlersCount = 0; // each label holds one handler per range (start/end contiguous)
 			for (int i = 0, length = this.codeStream.exceptionLabelsCounter; i < length; i++) {
-				exceptionHandlersCount += this.codeStream.exceptionLabels[i].count / 2;
+				exceptionHandlersCount += this.codeStream.exceptionLabels[i].getCount() / 2;
 			}
 			int exSize = exceptionHandlersCount * 8 + 2;
 			if (exSize + localContentsOffset >= this.contents.length) {
@@ -1792,7 +1792,7 @@
 			for (int i = 0, max = this.codeStream.exceptionLabelsCounter; i < max; i++) {
 				ExceptionLabel exceptionLabel = exceptionLabels[i];
 				if (exceptionLabel != null) {
-					int iRange = 0, maxRange = exceptionLabel.count;
+					int iRange = 0, maxRange = exceptionLabel.getCount();
 					if ((maxRange & 1) != 0) {
 						this.referenceBinding.scope.problemReporter().abortDueToInternalError(
 								Messages.bind(Messages.abort_invalidExceptionAttribute, new String(binding.selector),
@@ -3931,7 +3931,7 @@
 					i++;
 					break;
 				default:
-					throw new IllegalArgumentException();
+					throw new IllegalArgumentException("Invalid starting type character : " + currentCharacter); //$NON-NLS-1$
 			}
 		}
 	}
@@ -4075,24 +4075,14 @@
 			int resolvedPosition = 0;
 			// take into account enum constructor synthetic name+ordinal
 			final boolean isConstructor = methodBinding.isConstructor();
-			if (isConstructor) {
-				LocalVariableBinding localVariableBinding = new LocalVariableBinding("this".toCharArray(), methodBinding.declaringClass, 0, false); //$NON-NLS-1$
+			if (isConstructor || !methodBinding.isStatic()) {
+				LocalVariableBinding localVariableBinding = new LocalVariableBinding(ConstantPool.This, methodBinding.declaringClass, 0, false);
 				localVariableBinding.resolvedPosition = 0;
 				this.codeStream.record(localVariableBinding);
 				localVariableBinding.recordInitializationStartPC(0);
 				localVariableBinding.recordInitializationEndPC(codeLength);
 				frame.putLocal(resolvedPosition, new VerificationTypeInfo(
-						VerificationTypeInfo.ITEM_UNINITIALIZED_THIS,
-						methodBinding.declaringClass));
-				resolvedPosition++;
-			} else if (!methodBinding.isStatic()) {
-				LocalVariableBinding localVariableBinding = new LocalVariableBinding("this".toCharArray(), methodBinding.declaringClass, 0, false); //$NON-NLS-1$
-				localVariableBinding.resolvedPosition = 0;
-				this.codeStream.record(localVariableBinding);
-				localVariableBinding.recordInitializationStartPC(0);
-				localVariableBinding.recordInitializationEndPC(codeLength);
-				frame.putLocal(resolvedPosition, new VerificationTypeInfo(
-						VerificationTypeInfo.ITEM_OBJECT,
+						isConstructor ? VerificationTypeInfo.ITEM_UNINITIALIZED_THIS : VerificationTypeInfo.ITEM_OBJECT,
 						methodBinding.declaringClass));
 				resolvedPosition++;
 			}
@@ -4659,8 +4649,8 @@
 					break;
 				case Opcodes.OPC_aload_0:
 					VerificationTypeInfo locals0 = frame.locals[0];
-					// special case to handle uninitialized object
-					if (locals0 == null) {
+					if (locals0.tag != VerificationTypeInfo.ITEM_UNINITIALIZED_THIS) {
+						// special case to handle uninitialized object
 						locals0 = retrieveLocal(currentPC, 0);
 					}
 					frame.addStackItem(locals0);
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 20f097d..f8722ee 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: ASTNode.java 23405 2010-02-03 17:02:18Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995
@@ -39,7 +38,7 @@
 	// storage for internal flags (32 bits)				BIT USAGE
 	public final static int Bit1 = 0x1;					// return type (operator) | name reference kind (name ref) | add assertion (type decl) | useful empty statement (empty statement)
 	public final static int Bit2 = 0x2;					// return type (operator) | name reference kind (name ref) | has local type (type, method, field decl)
-	public final static int Bit3 = 0x4;					// return type (operator) | name reference kind (name ref) | implicit this (this ref) | locals (isArgument)
+	public final static int Bit3 = 0x4;					// return type (operator) | name reference kind (name ref) | implicit this (this ref)
 	public final static int Bit4 = 0x8;					// return type (operator) | first assignment to local (name ref,local decl) | undocumented empty block (block, type and method decl)
 	public final static int Bit5 = 0x10;					// value for return (expression) | has all method bodies (unit) | supertype ref (type ref) | resolved (field decl)
 	public final static int Bit6 = 0x20;					// depth (name ref, msg) | ignore need cast check (cast expression) | error in signature (method declaration/ initializer) | is recovered (annotation reference)
@@ -123,12 +122,12 @@
 	// for name references
 	public static final int RestrictiveFlagMASK = Bit1|Bit2|Bit3;
 
-	// for name refs or local decls
-	public static final int FirstAssignmentToLocal = Bit4;
-
 	// for local decls
 	public static final int IsArgument = Bit3;
 
+	// for name refs or local decls
+	public static final int FirstAssignmentToLocal = Bit4;
+
 	// for msg or field references
 	public static final int NeedReceiverGenericCast = Bit19;
 	
@@ -142,7 +141,7 @@
 	// for statements
 	public static final int IsReachable = Bit32;
 	public static final int LabelUsed = Bit7;
-	public static final int DocumentedFallthrough = Bit30;
+	public static final int DocumentedFallthrough = Bit30; // switch statement
 
 	// local decls
 	public static final int IsLocalDeclarationReachable = Bit31;
@@ -274,6 +273,16 @@
 	public static final int INVOCATION_ARGUMENT_UNCHECKED = 1;
 	public static final int INVOCATION_ARGUMENT_WILDCARD = 2;
 
+	// for type reference (diamond case) - Java 7
+	public static final int IsUnionType = Bit30;
+	// Used to tag ParameterizedSingleTypeReference or ParameterizedQualifiedTypeReference when they are
+	// used without any type args. It is also used to tag CompletionOnQualifiedExpression when the
+	// generics inference has failed and the resolved type still has <>.
+	public static final int IsDiamond = Bit20;
+
+	// this is only used for method invocation as the expression inside an expression statement
+	public static final int InsideExpressionStatement = Bit5;
+
 	public ASTNode() {
 
 		super();
@@ -300,6 +309,10 @@
   :giro */
 	public boolean checkInvocationArguments(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding method, Expression[] arguments, TypeBinding[] argumentTypes, boolean argsContainCast, InvocationSite invocationSite) {
 // SH}
+		boolean is1_7 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7;
+		if (is1_7 && method.isPolymorphic()) {
+			return false;
+		}
 		TypeBinding[] params = method.parameters;
 		int paramLength = params.length;
 		boolean isRawMemberInvocation = !method.isStatic()
@@ -321,9 +334,10 @@
 		if (arguments == null) {
 			if (method.isVarargs()) {
 				TypeBinding parameterType = ((ArrayBinding) params[paramLength-1]).elementsType(); // no element was supplied for vararg parameter
-		    	if (!parameterType.isReifiable()) {
-				    scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
-		    	}
+				if (!parameterType.isReifiable()
+						&& (!is1_7 || ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0))) {
+					scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
+				}
 			}
 		} else {
 			if (method.isVarargs()) {
@@ -333,18 +347,19 @@
 					TypeBinding originalRawParam = rawOriginalGenericMethod == null ? null : rawOriginalGenericMethod.parameters[i];
 					invocationStatus |= checkInvocationArgument(scope, arguments[i], params[i] , argumentTypes[i], originalRawParam);
 				}
-			   int argLength = arguments.length;
-			   if (lastIndex <= argLength) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337093
-				   	TypeBinding parameterType = params[lastIndex];
+				int argLength = arguments.length;
+				if (lastIndex <= argLength) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337093
+					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
-				    	if (!parameterType.isReifiable()) {
-						    scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
-				    	}
+					if (paramLength != argLength || parameterType.dimensions() != argumentTypes[lastIndex].dimensions()) {
+						parameterType = ((ArrayBinding) parameterType).elementsType(); // single element was provided for vararg parameter
+						if (!parameterType.isReifiable()
+								&& (!is1_7 || ((method.tagBits & TagBits.AnnotationSafeVarargs) == 0))) {
+							scope.problemReporter().unsafeGenericArrayForVarargs(parameterType, (ASTNode)invocationSite);
+						}
 						originalRawParam = rawOriginalGenericMethod == null ? null : ((ArrayBinding)rawOriginalGenericMethod.parameters[lastIndex]).elementsType();
-				    }
+					}
 					for (int i = lastIndex; i < argLength; i++) {
 						invocationStatus |= checkInvocationArgument(scope, arguments[i], parameterType, argumentTypes[i], originalRawParam);
 					}
@@ -383,7 +398,7 @@
 			}
 		}
 		if ((invocationStatus & INVOCATION_ARGUMENT_WILDCARD) != 0) {
-		    scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
+			scope.problemReporter().wildcardInvocation((ASTNode)invocationSite, receiverType, method, argumentTypes);
 		} else if (!method.isStatic() && !receiverType.isUnboundWildcard() && method.declaringClass.isRawType() && method.hasSubstitutedParameters()) {
 			if (scope.compilerOptions().reportUnavoidableGenericTypeProblems || receiver == null || !receiver.forcedToBeRaw(scope.referenceContext())) {
 				scope.problemReporter().unsafeRawInvocation((ASTNode)invocationSite, method);
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 9c4213f..0469e15 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: AllocationExpression.java 23405 2010-02-03 17:02:18Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contributions for 
@@ -16,12 +15,15 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
+import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 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.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
+import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.Dependencies;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
 import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateMemento;
@@ -60,6 +62,8 @@
 	public TypeReference[] typeArguments;
 	public TypeBinding[] genericTypeArguments;
 	public FieldDeclaration enumConstant; // for enum constant initializations
+	protected TypeBinding typeExpected;	  // for <> inference
+	public boolean inferredReturnType;
 
 //{ObjectTeams: alternate AST in case the creation needs to be redirected through a creator call:
 	private MessageSend roleCreatorCall = null;
@@ -354,6 +358,7 @@
 	}
 // SH}
 
+	final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
 	// resolve type arguments (for generic constructor call)
 	if (this.typeArguments != null) {
 		int length = this.typeArguments.length;
@@ -368,6 +373,10 @@
 				scope.problemReporter().illegalUsageOfWildcard(typeReference);
 			}
 		}
+		if (isDiamond) {
+			scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
+			return null;
+		}
 		if (argHasError) {
 			if (this.arguments != null) { // still attempt to resolve arguments
 				for (int i = 0, max = this.arguments.length; i < max; i++) {
@@ -396,8 +405,15 @@
 			}
 		}
 		if (argHasError) {
+			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
+			   No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
+			   not return the partially resolved type.
+			 */
+			if (isDiamond) {
+				return null; // not the partially cooked this.resolvedType
+			}
 			if (this.resolvedType instanceof ReferenceBinding) {
-				// record a best guess, for clients who need hint about possible contructor match
+				// record a best guess, for clients who need hint about possible constructor match
 				TypeBinding[] pseudoArgs = new TypeBinding[length];
 				for (int i = length; --i >= 0;) {
 					pseudoArgs[i] = argumentTypes[i] == null ? TypeBinding.NULL : argumentTypes[i]; // replace args with errors with null type
@@ -432,6 +448,14 @@
 		scope.problemReporter().cannotInstantiate(this.type, this.resolvedType);
 		return this.resolvedType;
 	}
+	if (isDiamond) {
+		TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) this.resolvedType).genericType(), null, argumentTypes, scope);
+		if (inferredTypes == null) {
+			scope.problemReporter().cannotInferElidedTypes(this);
+			return this.resolvedType = null;
+		}
+		this.resolvedType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) this.resolvedType).genericType(), inferredTypes, ((ParameterizedTypeBinding) this.resolvedType).enclosingType());
+ 	}
 	ReferenceBinding allocationType = (ReferenceBinding) this.resolvedType;
 //{ObjectTeams: may need to instantiate parameters of constructor
     AnchorMapping anchorMapping = AnchorMapping.setupNewMapping(null, this.arguments, scope);
@@ -478,6 +502,9 @@
 	if (this.typeArguments != null && this.binding.original().typeVariables == Binding.NO_TYPE_VARIABLES) {
 		scope.problemReporter().unnecessaryTypeArgumentsForMethodInvocation(this.binding, this.genericTypeArguments, this.typeArguments);
 	}
+	if (!isDiamond && this.resolvedType.isParameterizedTypeWithActualArguments()) {
+ 		checkTypeArgumentRedundancy((ParameterizedTypeBinding) this.resolvedType, null, argumentTypes, scope);
+ 	}
 //{ObjectTeams: may need to wrap the resolved type
     this.resolvedType = allocationType =
     	(ReferenceBinding)RoleTypeCreator.maybeWrapUnqualifiedRoleType(allocationType, scope, this);
@@ -512,6 +539,53 @@
 	return allocationType;
 }
 
+public TypeBinding[] inferElidedTypes(ReferenceBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
+	/* Given the allocation type and the arguments to the constructor, see if we can synthesize a generic static factory
+	   method that would, given the argument types and the invocation site, manufacture a parameterized object of type allocationType.
+	   If we are successful then by design and construction, the parameterization of the return type of the factory method is identical
+	   to the types elided in the <>.
+	 */   
+	MethodBinding factory = scope.getStaticFactory(allocationType, enclosingType, argumentTypes, this);
+	if (factory instanceof ParameterizedGenericMethodBinding && factory.isValidBinding()) {
+		ParameterizedGenericMethodBinding genericFactory = (ParameterizedGenericMethodBinding) factory;
+		this.inferredReturnType = genericFactory.inferredReturnType;
+		return ((ParameterizedTypeBinding)factory.returnType).arguments;
+	}
+	return null;
+}
+
+public void checkTypeArgumentRedundancy(ParameterizedTypeBinding allocationType, ReferenceBinding enclosingType, TypeBinding[] argumentTypes, final BlockScope scope) {
+	ProblemReporter reporter = scope.problemReporter();
+	if ((reporter.computeSeverity(IProblem.RedundantSpecificationOfTypeArguments) == ProblemSeverities.Ignore) || scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return;
+	if (allocationType.arguments == null) return;  // raw binding
+	if (this.genericTypeArguments != null) return; // diamond can't occur with explicit type args for constructor
+	if (argumentTypes == Binding.NO_PARAMETERS && this.typeExpected instanceof ParameterizedTypeBinding) {
+		ParameterizedTypeBinding expected = (ParameterizedTypeBinding) this.typeExpected;
+		if (expected.arguments != null && allocationType.arguments.length == expected.arguments.length) {
+			// check the case when no ctor takes no params and inference uses the expected type directly
+			// eg. X<String> x = new X<String>()
+			int i;
+			for (i = 0; i < allocationType.arguments.length; i++) {
+				if (allocationType.arguments[i] != expected.arguments[i])
+					break;
+			}
+			if (i == allocationType.arguments.length) {
+				reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
+				return;
+			}	
+		}
+	}
+	TypeBinding [] inferredTypes = inferElidedTypes(allocationType.genericType(), enclosingType, argumentTypes, scope);
+	if (inferredTypes == null) {
+		return;
+	}
+	for (int i = 0; i < inferredTypes.length; i++) {
+		if (inferredTypes[i] != allocationType.arguments[i])
+			return;
+	}
+	reporter.redundantSpecificationOfTypeArguments(this.type, allocationType.arguments);
+}
+
 //{ObjectTeams: replace with and resolved role creation expression:
 private TypeBinding resolveAsRoleCreationExpression(ReferenceBinding typeBinding, BlockScope scope) {
 	RoleModel roleModel = typeBinding.roleModel;
@@ -614,4 +688,17 @@
 	}
 	visitor.endVisit(this, scope);
 }
+/**
+ * @see org.eclipse.jdt.internal.compiler.ast.Expression#setExpectedType(org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+ */
+public void setExpectedType(TypeBinding expectedType) {
+	this.typeExpected = expectedType;
+}
+/**
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#expectedType()
+ */
+public TypeBinding expectedType() {
+	return this.typeExpected;
+}
+
 }
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 cfe7d56..4d9b543 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -168,6 +168,12 @@
 			case TypeIds.T_JavaLangSuppressWarnings :
 				tagBits |= TagBits.AnnotationSuppressWarnings;
 				break;
+			case TypeIds.T_JavaLangSafeVarargs :
+				tagBits |= TagBits.AnnotationSafeVarargs;
+				break;
+			case TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature :
+				tagBits |= TagBits.AnnotationPolymorphicSignature;
+				break;
 //{ObjectTeams: more standard annotations:
 			case IOTConstants.T_OrgObjectTeamsInstantiation :
 				tagBits |= TagBits.AnnotationInstantiation;
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 289ce10..7c5d33f 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: Argument.java 23137 2009-12-04 20:03:06Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
@@ -15,6 +14,7 @@
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 
@@ -38,8 +38,6 @@
 		this.declarationSourceEnd = (int) posNom;
 		this.modifiers = modifiers;
 		this.type = tr;
-		// always an argument by default. The bit IsArgument will be clear when this is used as
-		// catch formal parameter
 		this.bits |= (IsLocalDeclarationReachable | IsArgument);
 	}
 
@@ -164,13 +162,6 @@
 					hasError = true;
 					// fall thru to create the variable - avoids additional errors because the variable is missing
 					break;
-				case Binding.ARRAY_TYPE :
-					if (((ArrayBinding) exceptionType).leafComponentType == TypeBinding.VOID) {
-						scope.problemReporter().variableTypeCannotBeVoidArray(this);
-						hasError = true;
-						// fall thru to create the variable - avoids additional errors because the variable is missing
-					}
-					break;
 			}
 			if (exceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null && exceptionType.isValidBinding()) {
 				scope.problemReporter().cannotThrowType(this.type, exceptionType);
@@ -186,8 +177,13 @@
 				scope.problemReporter().localVariableHiding(this, existingVariable, false);
 			}
 		}
-
-		this.binding = new LocalVariableBinding(this, exceptionType, this.modifiers, false); // argument decl, but local var  (where isArgument = false)
+		
+		if ((this.type.bits & ASTNode.IsUnionType) != 0) {
+			this.binding = new CatchParameterBinding(this, exceptionType, this.modifiers | ClassFileConstants.AccFinal, false); // argument decl, but local var  (where isArgument = false)
+			this.binding.tagBits |= TagBits.MultiCatchParameter;
+		} else {
+			this.binding = new CatchParameterBinding(this, exceptionType, this.modifiers, false); // argument decl, but local var  (where isArgument = false)
+		}
 		resolveAnnotations(scope, this.annotations, this.binding);
 
 		scope.addLocalVariable(this.binding);
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 f8bfd7e..95d873c 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: Assignment.java 23405 2010-02-03 17:02:18Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Genady Beriozkin - added support for reporting assignment with no effect
@@ -175,6 +174,10 @@
 	if (lhsType != null) {
 		this.resolvedType = lhsType.capture(scope, this.sourceEnd);
 	}
+	LocalVariableBinding localVariableBinding = this.lhs.localVariableBinding();
+	if (localVariableBinding != null) {
+		localVariableBinding.tagBits &= ~TagBits.IsEffectivelyFinal;
+	}
 	TypeBinding rhsType = this.expression.resolveType(scope);
 	if (lhsType == null || rhsType == null) {
 		return null;
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 42bf559..13b2789 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -12,7 +12,7 @@
 
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
-import org.eclipse.jdt.internal.compiler.codegen.CaseLabel;
+import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
 import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.flow.FlowContext;
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
@@ -27,7 +27,7 @@
 public class CaseStatement extends Statement {
 
 	public Expression constantExpression;
-	public CaseLabel targetLabel;
+	public BranchLabel targetLabel;
 
 public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) {
 	this.constantExpression = constantExpression;
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 b2d1d20..08c2de8 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
@@ -30,6 +30,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
@@ -624,6 +625,14 @@
 		exprContainCast = true;
 	}
 	TypeBinding expressionType = this.expression.resolveType(scope);
+	if (this.expression instanceof MessageSend) {
+		MessageSend messageSend = (MessageSend) this.expression;
+		MethodBinding methodBinding = messageSend.binding;
+		if (methodBinding != null && methodBinding.isPolymorphic()) {
+			messageSend.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) methodBinding, castType);
+			expressionType = castType;
+		}
+	}
 //{ObjectTeams: de-wrap tthis-expressiontType if this statement was generated:
 	if (expressionType instanceof WeakenedTypeBinding)
 		expressionType = ((WeakenedTypeBinding)expressionType).weakenedType; // pessimistic
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 f03028c..4addf30 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
@@ -224,7 +224,7 @@
 								if (count > ENUM_CONSTANTS_THRESHOLD) {
 									SyntheticMethodBinding syntheticMethod = declaringType.binding.addSyntheticMethodForEnumInitialization(begin, i);
 									codeStream.invoke(Opcodes.OPC_invokestatic, syntheticMethod, null /* default declaringClass */);
-									begin = -1;
+									begin = i;
 									count = 0;
 								}
 							}
@@ -354,11 +354,7 @@
 			}
 			// Record the end of the clinit: point to the declaration of the class
 			codeStream.recordPositionsFrom(0, declaringType.sourceStart);
-			try {
-				classFile.completeCodeAttributeForClinit(codeAttributeOffset);
-			} catch(NegativeArraySizeException e) {
-				throw new AbortMethod(this.scope.referenceCompilationUnit().compilationResult, null);
-			}
+			classFile.completeCodeAttributeForClinit(codeAttributeOffset);
 		}
 	}
 
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 29d200a..94f88df 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
@@ -272,7 +272,8 @@
 		CategorizedProblem problem = problems[iProblem];
 		int problemID = problem.getID();
 		int irritant = ProblemReporter.getIrritant(problemID);
-		if (problem.isError()) {
+		boolean isError = problem.isError();
+		if (isError) {
 			if (irritant == 0) {
 				// tolerate unused warning tokens when mandatory errors
 				hasMandatoryErrors = true;
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 e8d82e6..d4eab06 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
@@ -4,7 +4,7 @@
  * are made 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
  *******************************************************************************/
@@ -125,7 +125,10 @@
 		TypeBinding originalExpressionType = this.expression.resolveType(scope);
 		if (originalLhsType == null || originalExpressionType == null)
 			return null;
-
+		LocalVariableBinding localVariableBinding = this.lhs.localVariableBinding();
+		if (localVariableBinding != null) {
+			localVariableBinding.tagBits &= ~TagBits.IsEffectivelyFinal;
+		}
 		// autoboxing support
 		LookupEnvironment env = scope.environment();
 		TypeBinding lhsType = originalLhsType, expressionType = originalExpressionType;
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 245c98f..1a7ef12 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
  *******************************************************************************/
 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.impl.*;
 import org.eclipse.jdt.internal.compiler.codegen.*;
@@ -26,6 +27,11 @@
 
 public void computeConstant() {
 	Double computedValue;
+	boolean containsUnderscores = CharOperation.indexOf('_', this.source) > 0;
+	if (containsUnderscores) {
+		// remove all underscores from source
+		this.source = CharOperation.remove(this.source, '_');
+	}
 	try {
 		computedValue = Double.valueOf(String.valueOf(this.source));
 	} catch (NumberFormatException e) {
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 e42c634..f3e4b26 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
  *******************************************************************************/
 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.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.impl.FloatConstant;
@@ -27,6 +28,11 @@
 
 public void computeConstant() {
 	Float computedValue;
+	boolean containsUnderscores = CharOperation.indexOf('_', this.source) > 0;
+	if (containsUnderscores) {
+		// remove all underscores from source
+		this.source = CharOperation.remove(this.source, '_');
+	}
 	try {
 		computedValue = Float.valueOf(String.valueOf(this.source));
 	} catch (NumberFormatException e) {
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 498713f..2fa4070 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,82 +10,149 @@
  *******************************************************************************/
 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.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.impl.IntConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
 
 public class IntLiteral extends NumberLiteral {
-	
+	private static final char[] HEXA_MIN_VALUE        = "0x80000000".toCharArray(); //$NON-NLS-1$
+	private static final char[] HEXA_MINUS_ONE_VALUE  = "0xffffffff".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MIN_VALUE       = "020000000000".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MINUS_ONE_VALUE = "037777777777".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MIN_VALUE     = "2147483648".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MAX_VALUE     = "2147483647".toCharArray(); //$NON-NLS-1$
+
+	private char[] reducedForm; // no underscores
+
 	public int value;
 
-	public static final IntLiteral One = new IntLiteral(new char[]{'1'},0,0,1);//used for ++ and --
-	
-public IntLiteral(char[] token, int s, int e) {
-	super(token, s,e);
-}
+	//used for ++ and --
+	public static final IntLiteral One = new IntLiteral(new char[]{'1'}, null, 0, 0, 1, IntConstant.fromValue(1));
 
-public IntLiteral(char[] token, int s,int e, int value) {
-	this(token, s,e);
+	public static IntLiteral buildIntLiteral(char[] token, int s, int e) {
+		// remove '_' and prefix '0' first
+		char[] intReducedToken = removePrefixZerosAndUnderscores(token, false);
+		switch(intReducedToken.length) {
+			case 10 :
+				// 0x80000000
+				if (CharOperation.equals(intReducedToken, HEXA_MIN_VALUE)) {
+					return new IntLiteralMinValue(token, intReducedToken != token ? intReducedToken : null, s, e);
+				}
+				break;
+			case 12 :
+				// 020000000000
+				if (CharOperation.equals(intReducedToken, OCTAL_MIN_VALUE)) {
+					return new IntLiteralMinValue(token, intReducedToken != token ? intReducedToken : null, s, e);
+				}
+				break;
+		}
+		return new IntLiteral(token, intReducedToken != token ? intReducedToken : null, s, e);
+	}
+IntLiteral(char[] token, char[] reducedForm, int start, int end) {
+	super(token, start, end);
+	this.reducedForm = reducedForm;
+}
+IntLiteral(char[] token, char[] reducedForm, int start, int end, int value, Constant constant) {
+	super(token, start, end);
+	this.reducedForm = reducedForm;
 	this.value = value;
+	this.constant = constant;
 }
 public void computeConstant() {
-	//a special constant is use for the potential Integer.MAX_VALUE+1
-	//which is legal if used with a - as prefix....cool....
-	//notice that Integer.MIN_VALUE  == -2147483648
-	long MAX = Integer.MAX_VALUE;
-	if (this == One) {	
-		this.constant = IntConstant.fromValue(1); 
-		return ;
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	int tokenLength = token.length;
+	int radix = 10;
+	int j = 0;
+	if (token[0] == '0') {
+		if (tokenLength == 1) {
+			this.constant = IntConstant.fromValue(0);
+			return;
+		}
+		if ((token[1] == 'x') || (token[1] == 'X')) {
+			radix = 16;
+			j = 2;
+		} else if ((token[1] == 'b') || (token[1] == 'B')) {
+			radix = 2;
+			j = 2;
+		} else {
+			radix = 8;
+			j = 1;
+		}
 	}
-	int length = this.source.length;
-	long computedValue = 0L;
-	if (this.source[0] == '0') {	
-		MAX = 0xFFFFFFFFL ; //a long in order to be positive !
-		if (length == 1) {
-			this.constant = IntConstant.fromValue(0); return ;
-		}
-		final int shift,radix;
-		int j ;
-		if ((this.source[1] == 'x') || (this.source[1] == 'X')) {	
-			shift = 4 ; j = 2; radix = 16;
-		} else {	
-			shift = 3 ; j = 1; radix = 8;
-		}
-		while (this.source[j]=='0')	 {	
-			j++; //jump over redondant zero
-			if (j == length) {
-				//watch for 000000000000000000
-				this.constant = IntConstant.fromValue(this.value = (int)computedValue);
+	switch(radix) {
+		case 2 :
+			if ((tokenLength - 2) > 32) {
+				// remove 0b or 0B
+				return; /*constant stays null*/
+			}
+			computeValue(token, tokenLength, radix, j);
+			return;
+		case 16 :
+			if (tokenLength <= 10) {
+				if (CharOperation.equals(token, HEXA_MINUS_ONE_VALUE)) {
+					this.constant = IntConstant.fromValue(-1);
+					return;
+				}
+				computeValue(token, tokenLength, radix, j);
 				return;
 			}
-		}
-		while (j<length) {	
-			int digitValue ;
-			if ((digitValue = ScannerHelper.digit(this.source[j++],radix))	< 0 ) {
+			break;
+		case 10 :
+			if (tokenLength > DECIMAL_MAX_VALUE.length
+					|| (tokenLength == DECIMAL_MAX_VALUE.length
+							&& CharOperation.compareTo(token, DECIMAL_MAX_VALUE) > 0)) {
 				return; /*constant stays null*/
 			}
-			computedValue = (computedValue<<shift) | digitValue ;
-			if (computedValue > MAX) return; /*constant stays null*/
-		}
-	} else {	
-		//-----------regular case : radix = 10-----------
-		for (int i = 0 ; i < length;i++) {	
-			int digitValue ;
-			if ((digitValue = ScannerHelper.digit(this.source[i],10))	< 0 ) {
-				return; /*constant stays null*/
+			computeValue(token, tokenLength, radix, j);
+			break;
+		case 8 :
+			if (tokenLength <= 12) {
+				if (tokenLength == 12 && token[j] > '4') {
+					return; /*constant stays null*/
+				}
+				if (CharOperation.equals(token, OCTAL_MINUS_ONE_VALUE)) {
+					this.constant = IntConstant.fromValue(-1);
+					return;
+				}
+				computeValue(token, tokenLength, radix, j);
+				return;
 			}
-			computedValue = 10*computedValue + digitValue;
-			if (computedValue > MAX) return /*constant stays null*/ ;
-		}
+			break;
 	}
-	this.constant = IntConstant.fromValue(this.value = (int)computedValue);
-
 }
-
+private void computeValue(char[] token, int tokenLength, int radix, int j) {
+	int digitValue;
+	int computedValue = 0;
+	while (j < tokenLength) {
+		if ((digitValue = ScannerHelper.digit(token[j++],radix)) < 0) {
+			return; /*constant stays null*/
+		}
+		computedValue = (computedValue * radix) + digitValue ;
+	}
+	this.constant = IntConstant.fromValue(computedValue);
+}
+public IntLiteral convertToMinValue() {
+	if (((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+		return this;
+	}
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	switch(token.length) {
+		case 10 :
+			// 2147483648
+			if (CharOperation.equals(token, DECIMAL_MIN_VALUE)) {
+				return new IntLiteralMinValue(this.source, this.reducedForm, this.sourceStart, this.sourceEnd);
+			}
+			break;
+	}
+	return this;
+}
 /**
- * Code generation for int literal
+ * Code generation for long literal
  *
  * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
  * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
@@ -102,25 +169,6 @@
 public TypeBinding literalType(BlockScope scope) {
 	return TypeBinding.INT;
 }
-
-public final boolean mayRepresentMIN_VALUE(){
-	//a special autorized int literral is 2147483648
-	//which is ONE over the limit. This special case
-	//only is used in combinaison with - to denote
-	//the minimal value of int -2147483648
-	return ((this.source.length == 10) &&
-			(this.source[0] == '2') &&
-			(this.source[1] == '1') &&
-			(this.source[2] == '4') &&
-			(this.source[3] == '7') &&
-			(this.source[4] == '4') &&
-			(this.source[5] == '8') &&
-			(this.source[6] == '3') &&
-			(this.source[7] == '6') &&
-			(this.source[8] == '4') &&
-			(this.source[9] == '8') &&
-			(((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0));
-}
 public void traverse(ASTVisitor visitor, BlockScope scope) {
 	visitor.visit(this, scope);
 	visitor.endVisit(this, scope);
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 d4d23e3..f175fe7 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -16,9 +16,8 @@
 
 	final static char[] CharValue = new char[]{'-','2','1','4','7','4','8','3','6','4','8'};
 
-public IntLiteralMinValue() {
-	super(CharValue,0,0,Integer.MIN_VALUE);
-	this.constant = IntConstant.fromValue(Integer.MIN_VALUE);
+public IntLiteralMinValue(char[] token, char[] reducedToken, int start, int end) {
+	super(token, reducedToken, start, end, Integer.MIN_VALUE, IntConstant.fromValue(Integer.MIN_VALUE));
 }
 
 public void computeConstant(){
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 063ac7b..87ca75c 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,88 +10,135 @@
  *******************************************************************************/
 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.impl.*;
-import org.eclipse.jdt.internal.compiler.codegen.*;
-import org.eclipse.jdt.internal.compiler.lookup.*;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.impl.LongConstant;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
 
 public class LongLiteral extends NumberLiteral {
 
-public LongLiteral(char[] token, int s,int e) {
-	super(token, s,e);
-}
+	private static final char[] HEXA_MIN_VALUE        = "0x8000000000000000L".toCharArray(); //$NON-NLS-1$
+	private static final char[] HEXA_MINUS_ONE_VALUE  = "0xffffffffffffffffL".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MIN_VALUE       = "01000000000000000000000L".toCharArray(); //$NON-NLS-1$
+	private static final char[] OCTAL_MINUS_ONE_VALUE = "01777777777777777777777L".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MIN_VALUE     = "9223372036854775808L".toCharArray(); //$NON-NLS-1$
+	private static final char[] DECIMAL_MAX_VALUE     = "9223372036854775807L".toCharArray(); //$NON-NLS-1$
 
+	private char[] reducedForm; // no underscores
+
+	public static LongLiteral buildLongLiteral(char[] token, int s, int e) {
+		// remove '_' and prefix '0' first
+		char[] longReducedToken = removePrefixZerosAndUnderscores(token, true);
+		switch(longReducedToken.length) {
+			case 19 :
+				// 0x8000000000000000L
+				if (CharOperation.equals(longReducedToken, HEXA_MIN_VALUE)) {
+					return new LongLiteralMinValue(token, longReducedToken != token ? longReducedToken : null, s, e);
+				}
+				break;
+			case 24 :
+				// 01000000000000000000000L
+				if (CharOperation.equals(longReducedToken, OCTAL_MIN_VALUE)) {
+					return new LongLiteralMinValue(token, longReducedToken != token ? longReducedToken : null, s, e);
+				}
+				break;
+		}
+		return new LongLiteral(token, longReducedToken != token ? longReducedToken : null, s, e);
+	}
+
+LongLiteral(char[] token, char[] reducedForm, int start, int end) {
+	super(token, start, end);
+	this.reducedForm = reducedForm;
+}
+public LongLiteral convertToMinValue() {
+	if (((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+		return this;
+	}
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	switch(token.length) {
+		case 20 :
+			// 9223372036854775808L
+			if (CharOperation.equals(token, DECIMAL_MIN_VALUE, false)) {
+				return new LongLiteralMinValue(this.source, this.reducedForm, this.sourceStart, this.sourceEnd);
+			}
+			break;
+	}
+	return this;
+}
 public void computeConstant() {
-	//the overflow (when radix=10) is tested using the fact that
-	//the value should always grow during its computation
-	int length = this.source.length - 1; //minus one because the last char is 'l' or 'L'
-	long computedValue ;
-	if (this.source[0] == '0') {
+	char[] token = this.reducedForm != null ? this.reducedForm : this.source;
+	int tokenLength = token.length;
+	int length = tokenLength - 1;
+	int radix = 10;
+	int j = 0;
+	if (token[0] == '0') {
 		if (length == 1) {
 			this.constant = LongConstant.fromValue(0L);
 			return;
 		}
-		final int shift,radix;
-		int j ;
-		if ( (this.source[1] == 'x') || (this.source[1] == 'X') ) {
-			shift = 4 ; j = 2; radix = 16;
+		if ((token[1] == 'x') || (token[1] == 'X')) {
+			radix = 16;
+			j = 2;
+		} else if ((token[1] == 'b') || (token[1] == 'B')) {
+			radix = 2;
+			j = 2;
 		} else {
-			shift = 3 ; j = 1; radix = 8;
+			radix = 8;
+			j = 1;
 		}
-		int nbDigit = 0;
-		while (this.source[j]=='0') {
-			j++; //jump over redondant zero
-			if ( j == length) {
-				//watch for 0000000000000L
-				this.constant = LongConstant.fromValue(0L);
-				return;
+	}
+	switch(radix) {
+		case 2 :
+			if ((length - 2) > 64) { // remove 0b or 0B
+				return; /*constant stays null*/
 			}
-		}
-
-		int digitValue ;
-		if ((digitValue = ScannerHelper.digit(this.source[j++],radix)) < 0 ) {
+			computeValue(token, length, radix, j);
+			break;
+		case 16 :
+			if (tokenLength <= 19) {
+				if (CharOperation.equals(token, HEXA_MINUS_ONE_VALUE)) {
+					this.constant = LongConstant.fromValue(-1L);
+					return;
+				}
+				computeValue(token, length, radix, j);
+			}
+			break;
+		case 10 :
+			if (tokenLength > DECIMAL_MAX_VALUE.length
+					|| (tokenLength == DECIMAL_MAX_VALUE.length
+							&& CharOperation.compareTo(token, DECIMAL_MAX_VALUE, 0, length) > 0)) {
+				return; /*constant stays null*/
+			}
+			computeValue(token, length, radix, j);
+			break;
+		case 8 :
+			if (tokenLength <= 24) {
+				if (tokenLength == 24 && token[j] > '1') {
+					return; /*constant stays null*/
+				}
+				if (CharOperation.equals(token, OCTAL_MINUS_ONE_VALUE)) {
+					this.constant = LongConstant.fromValue(-1L);
+					return;
+				}
+				computeValue(token, length, radix, j);
+			}
+			break;
+	}
+}
+private void computeValue(char[] token, int tokenLength, int radix, int j) {
+	int digitValue;
+	long computedValue = 0;
+	while (j < tokenLength) {
+		if ((digitValue = ScannerHelper.digit(token[j++],radix)) < 0) {
 			return; /*constant stays null*/
 		}
-		if (digitValue >= 8)
-			nbDigit = 4;
-		else if (digitValue >= 4)
-			nbDigit = 3;
-		else if (digitValue >= 2)
-			nbDigit = 2;
-		else
-			nbDigit = 1; //digitValue is not 0
-		computedValue = digitValue ;
-		while (j<length) {
-			if ((digitValue = ScannerHelper.digit(this.source[j++],radix)) < 0) {
-				return; /*constant stays null*/
-			}
-			if ((nbDigit += shift) > 64)
-				return; /*constant stays null*/
-			computedValue = (computedValue<<shift) | digitValue ;
-		}
-	} else {
-		//-----------case radix=10-----------------
-		long previous = 0;
-		computedValue = 0;
-		final long limit = Long.MAX_VALUE / 10; // needed to check prior to the multiplication
-		for (int i = 0 ; i < length; i++) {
-			int digitValue ;
-			if ((digitValue = ScannerHelper.digit(this.source[i], 10)) < 0 ) return /*constant stays null*/;
-			previous = computedValue;
-			if (computedValue > limit)
-				return; /*constant stays null*/
-			computedValue *= 10;
-			if ((computedValue + digitValue) > Long.MAX_VALUE)
-				return; /*constant stays null*/
-			computedValue += digitValue;
-			if (previous > computedValue)
-				return; /*constant stays null*/
-		}
+		computedValue = (computedValue * radix) + digitValue ;
 	}
 	this.constant = LongConstant.fromValue(computedValue);
 }
-
 /**
  * Code generation for long literal
  *
@@ -110,35 +157,6 @@
 public TypeBinding literalType(BlockScope scope) {
 	return TypeBinding.LONG;
 }
-
-public final boolean mayRepresentMIN_VALUE(){
-	//a special autorized int literral is 9223372036854775808L
-	//which is ONE over the limit. This special case
-	//only is used in combinaison with - to denote
-	//the minimal value of int -9223372036854775808L
-	return ((this.source.length == 20) &&
-			(this.source[0] == '9') &&
-			(this.source[1] == '2') &&
-			(this.source[2] == '2') &&
-			(this.source[3] == '3') &&
-			(this.source[4] == '3') &&
-			(this.source[5] == '7') &&
-			(this.source[6] == '2') &&
-			(this.source[7] == '0') &&
-			(this.source[8] == '3') &&
-			(this.source[9] == '6') &&
-			(this.source[10] == '8') &&
-			(this.source[11] == '5') &&
-			(this.source[12] == '4') &&
-			(this.source[13] == '7') &&
-			(this.source[14] == '7') &&
-			(this.source[15] == '5') &&
-			(this.source[16] == '8') &&
-			(this.source[17] == '0') &&
-			(this.source[18] == '8') &&
-			(((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0));
-}
-
 public void traverse(ASTVisitor visitor, BlockScope scope) {
 	visitor.visit(this, scope);
 	visitor.endVisit(this, scope);
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 384b28e..962b874 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -16,8 +16,8 @@
 
 	final static char[] CharValue = new char[]{'-', '9','2','2','3','3','7','2','0','3','6','8','5','4','7','7','5','8','0','8','L'};
 
-public LongLiteralMinValue(){
-	super(CharValue,0,0);
+public LongLiteralMinValue(char[] token, char[] reducedForm, int start, int end) {
+	super(token, reducedForm, start, end);
 	this.constant = LongConstant.fromValue(Long.MIN_VALUE);
 }
 public void computeConstant() {
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 ed845c5..f201f4a 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
@@ -37,6 +37,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolymorphicMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
@@ -272,7 +273,7 @@
 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
 	int pc = codeStream.position;
 	// generate receiver/enclosing instance access
-	MethodBinding codegenBinding = this.binding.original();
+	MethodBinding codegenBinding = this.binding instanceof PolymorphicMethodBinding ? this.binding : this.binding.original();
 	boolean isStatic = codegenBinding.isStatic();
 	if (isStatic) {
 		this.receiver.generateCode(currentScope, codeStream, false);
@@ -837,10 +838,21 @@
     	}
     }
 // SH}
+	final CompilerOptions compilerOptions = scope.compilerOptions();
+	if (compilerOptions.complianceLevel <= ClassFileConstants.JDK1_6
+			&& this.binding.isPolymorphic()) {
+		scope.problemReporter().polymorphicMethodNotBelow17(this);
+		return null;
+	}
+
+	if (((this.bits & ASTNode.InsideExpressionStatement) != 0)
+			&& this.binding.isPolymorphic()) {
+		// we only set the return type to be void if this method invocation is used inside an expression statement
+		this.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) this.binding, TypeBinding.VOID);
+	}
 	if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
 		scope.problemReporter().missingTypeInMethod(this, this.binding);
 	}
-	final CompilerOptions compilerOptions = scope.compilerOptions();
 	if (!this.binding.isStatic()) {
 		// the "receiver" must not be a type
 		if (receiverIsType) {
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 c556478..f73810e 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -30,4 +30,62 @@
 	public char[] source(){
 		return this.source;
 	}
+	protected static char[] removePrefixZerosAndUnderscores(char[] token, boolean isLong) {
+		int max = token.length;
+		int start = 0;
+		int end = max - 1;
+		if (isLong) {
+			end--; // remove the 'L' or 'l'
+		}
+		if (max > 1 && token[0] == '0') {
+			if (max > 2 && (token[1] == 'x' || token[1] == 'X')) {
+				start = 2;
+			} else if (max > 2 && (token[1] == 'b' || token[1] == 'B')) {
+				start = 2;
+			} else {
+				start = 1;
+			}
+		}
+		boolean modified = false;
+		boolean ignore = true;
+		loop: for (int i = start; i < max; i++) {
+			char currentChar = token[i];
+			switch(currentChar) {
+				case '0' :
+					// this is a prefix '0'
+					if (ignore && !modified && (i < end)) {
+						modified = true;
+					}
+					break;
+				case '_' :
+					modified = true;
+					break loop;
+				default :
+					ignore = false;
+			}
+		}
+		if (!modified) {
+			return token;
+		}
+		ignore = true;
+		StringBuffer buffer = new StringBuffer();
+		buffer.append(token, 0, start);
+		loop: for (int i = start; i < max; i++) {
+			char currentChar = token[i];
+			switch(currentChar) {
+				case '0' :
+					if (ignore && (i < end)) {
+						// this is a prefix '0'
+						continue loop;
+					}
+					break;
+				case '_' :
+					continue loop;
+				default:
+					ignore = false;
+			}
+			buffer.append(currentChar);
+		}
+		return buffer.toString().toCharArray();
+	}
 }
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 2af64e4..bf41a61 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
@@ -228,6 +228,7 @@
 			    	((ClassScope) scope).superTypeReference = null;
 			    }
 				int argLength = args.length;
+				boolean isDiamond = argLength == 0 && (i == (max -1)) && ((this.bits & ASTNode.IsDiamond) != 0);
 				TypeBinding[] argTypes = new TypeBinding[argLength];
 				boolean argHasError = false;
 				ReferenceBinding currentOriginal = (ReferenceBinding)currentType.original();
@@ -261,9 +262,11 @@
 						? scope.environment().createParameterizedType(currentOriginal, null, qualifyingType)
 						: currentType;
 					return this.resolvedType;
-				} else if (argLength != typeVariables.length) { // check arity
-					scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes, i);
-					return null;
+				} else if (argLength != typeVariables.length) {
+					if (!isDiamond) { // check arity
+						scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes, i);
+						return null;
+					}
 				}
 				// check parameterizing non-static member type of raw type
 				if (typeIsConsistent && !currentType.isStatic()) {
@@ -275,11 +278,13 @@
 					}
 				}
 				ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType(currentOriginal, argTypes, qualifyingType);
-				// check argument type compatibility
-				if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
-					parameterizedType.boundCheck(scope, args);
-				else
-					scope.deferBoundCheck(this);
+				// check argument type compatibility for non <> cases - <> case needs no bounds check, we will scream foul if needed during inference.
+				if (!isDiamond) {
+					if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
+						parameterizedType.boundCheck(scope, args);
+					else
+						scope.deferBoundCheck(this);
+				}
 				qualifyingType = parameterizedType;
 		    } else {
 				ReferenceBinding currentOriginal = (ReferenceBinding)currentType.original();
@@ -319,12 +324,15 @@
 			TypeReference[] typeArgument = this.typeArguments[i];
 			if (typeArgument != null) {
 				output.append('<');
-				int max = typeArgument.length - 1;
-				for (int j = 0; j < max; j++) {
-					typeArgument[j].print(0, output);
-					output.append(", ");//$NON-NLS-1$
+				int typeArgumentLength = typeArgument.length;
+				if (typeArgumentLength > 0) {
+					int max = typeArgumentLength - 1;
+					for (int j = 0; j < max; j++) {
+						typeArgument[j].print(0, output);
+						output.append(", ");//$NON-NLS-1$
+					}
+					typeArgument[max].print(0, output);
 				}
-				typeArgument[max].print(0, output);
 				output.append('>');
 			}
 			output.append('.');
@@ -333,12 +341,15 @@
 		TypeReference[] typeArgument = this.typeArguments[length - 1];
 		if (typeArgument != null) {
 			output.append('<');
-			int max = typeArgument.length - 1;
-			for (int j = 0; j < max; j++) {
-				typeArgument[j].print(0, output);
-				output.append(", ");//$NON-NLS-1$
+			int typeArgumentLength = typeArgument.length;
+			if (typeArgumentLength > 0) {
+				int max = typeArgumentLength - 1;
+				for (int j = 0; j < max; j++) {
+					typeArgument[j].print(0, output);
+					output.append(", ");//$NON-NLS-1$
+				}
+				typeArgument[max].print(0, output);
 			}
-			typeArgument[max].print(0, output);
 			output.append('>');
 		}
 		if ((this.bits & IsVarArgs) != 0) {
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 d52c69b..6def1cb 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: ParameterizedSingleTypeReference.java 23405 2010-02-03 17:02:18Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding
@@ -342,6 +341,7 @@
 			return this.resolvedType;
 // SH}
 
+		final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
 		TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
 		if (typeVariables == Binding.NO_TYPE_VARIABLES) { // non generic invoked with arguments
 			boolean isCompliant15 = scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5;
@@ -359,9 +359,11 @@
 				return this.resolvedType = currentType;
 			}
 			// if missing generic type, and compliance >= 1.5, then will rebuild a parameterized binding
-		} else if (argLength != typeVariables.length) { // check arity
-			scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes);
-			return null;
+		} else if (argLength != typeVariables.length) {
+			if (!isDiamond) { // check arity, IsDiamond never set for 1.6-
+				scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes);
+				return null;
+			} 
 		} else if (!currentType.isStatic()) {
 			ReferenceBinding actualEnclosing = currentType.enclosingType();
 			if (actualEnclosing != null && actualEnclosing.isRawType()){
@@ -372,11 +374,13 @@
 		}
 
     	ParameterizedTypeBinding parameterizedType = scope.environment().createParameterizedType(currentOriginal, argTypes, enclosingType);
-		// check argument type compatibility
-		if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
-			parameterizedType.boundCheck(scope, this.typeArguments);
-		else
-			scope.deferBoundCheck(this);
+		// check argument type compatibility for non <> cases - <> case needs no bounds check, we will scream foul if needed during inference.
+    	if (!isDiamond) {
+    		if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method resolution
+    			parameterizedType.boundCheck(scope, this.typeArguments);
+    		else
+    			scope.deferBoundCheck(this);
+    	}
 		if (isTypeUseDeprecated(parameterizedType, scope))
 			reportDeprecatedType(parameterizedType, scope);
 
@@ -397,27 +401,25 @@
 	public StringBuffer printExpression(int indent, StringBuffer output){
 		output.append(this.token);
 		output.append("<"); //$NON-NLS-1$
-		int max = this.typeArguments.length - 1;
+		int length = this.typeArguments.length;
 //{ObjectTeams: value parameters:
 		if (this.typeAnchors != null) {
 			int anchorLen = this.typeAnchors.length;
 			for (int i = 0; i < anchorLen; i++) {
 				this.typeAnchors[i].print(0, output);
-				if (i+1 < anchorLen || max >= 0)
+				if (i+1 < anchorLen || length > 0)
 					output.append(", "); //$NON-NLS-1$
 			}
 		}
-	  // after filtering out value parameters, an empty array may remain:
-	  if (max >= 0) {
-// orig:
-		for (int i= 0; i < max; i++) {
-			this.typeArguments[i].print(0, output);
-			output.append(", ");//$NON-NLS-1$
-		}
-		this.typeArguments[max].print(0, output);
-// :giro
-	  }
 // SH}
+		if (length > 0) {
+			int max = length - 1;
+			for (int i= 0; i < max; i++) {
+				this.typeArguments[i].print(0, output);
+				output.append(", ");//$NON-NLS-1$
+			}
+			this.typeArguments[max].print(0, output);
+		}
 		output.append(">"); //$NON-NLS-1$
 		if ((this.bits & IsVarArgs) != 0) {
 			for (int i= 0 ; i < this.dimensions - 1; i++) {
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 18a692b..c9e36db 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: QualifiedAllocationExpression.java 23405 2010-02-03 17:02:18Z stephan $
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
@@ -26,6 +25,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
 import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
@@ -379,6 +379,7 @@
 		}
 
 		// resolve type arguments (for generic constructor call)
+		final boolean isDiamond = this.type != null && (this.type.bits & ASTNode.IsDiamond) != 0;
 		if (this.typeArguments != null) {
 			int length = this.typeArguments.length;
 			boolean argHasError = scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5;
@@ -392,6 +393,10 @@
 					scope.problemReporter().illegalUsageOfWildcard(typeReference);
 				}
 			}
+			if (isDiamond) {
+				scope.problemReporter().diamondNotWithExplicitTypeArguments(this.typeArguments);
+				return null;
+			}
 			if (argHasError) {
 				if (this.arguments != null) { // still attempt to resolve arguments
 					for (int i = 0, max = this.arguments.length; i < max; i++) {
@@ -421,6 +426,13 @@
 
 		// limit of fault-tolerance
 		if (hasError) {
+			/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=345359, if arguments have errors, completely bail out in the <> case.
+			   No meaningful type resolution is possible since inference of the elided types is fully tied to argument types. Do
+			   not return the partially resolved type.
+			 */
+			if (isDiamond) {
+				return null; // not the partially cooked this.resolvedType
+			}
 //{ObjectTeams: prevent a faulty anonymous type from being processed!
 			if (this.anonymousType != null)
 				this.anonymousType.tagAsHavingErrors();
@@ -467,6 +479,14 @@
 				scope.problemReporter().cannotInstantiate(this.type, receiverType);
 				return this.resolvedType = receiverType;
 			}
+			if (isDiamond) {
+				TypeBinding [] inferredTypes = inferElidedTypes(((ParameterizedTypeBinding) receiverType).genericType(), receiverType.enclosingType(), argumentTypes, scope);
+				if (inferredTypes == null) {
+					scope.problemReporter().cannotInferElidedTypes(this);
+					return this.resolvedType = null;
+				}
+				receiverType = this.type.resolvedType = scope.environment().createParameterizedType(((ParameterizedTypeBinding) receiverType).genericType(), inferredTypes, ((ParameterizedTypeBinding) receiverType).enclosingType());
+			}
 			ReferenceBinding allocationType = (ReferenceBinding) receiverType;
 //{ObjectTeams: setup context for constructor lookup:
             if (receiverType instanceof ReferenceBinding) // funny thing: receiver could be array..
@@ -518,6 +538,9 @@
 			if ((this.binding.tagBits & TagBits.HasMissingType) != 0) {
 				scope.problemReporter().missingTypeInConstructor(this, this.binding);
 			}
+			if (!isDiamond && receiverType.isParameterizedTypeWithActualArguments()) {
+		 		checkTypeArgumentRedundancy((ParameterizedTypeBinding)receiverType, receiverType.enclosingType(), argumentTypes , scope);
+		 	}
 			// The enclosing instance must be compatible with the innermost enclosing type
 			ReferenceBinding expectedType = this.binding.declaringClass.enclosingType();
 			if (expectedType != enclosingInstanceType) // must call before computeConversion() and typeMismatchError()
@@ -535,6 +558,11 @@
 			}
 			scope.problemReporter().typeMismatchError(enclosingInstanceType, expectedType, this.enclosingInstance, null);
 			return this.resolvedType = receiverType;
+		} else {
+			if (isDiamond) {
+				scope.problemReporter().diamondNotWithAnoymousClasses(this.type);
+				return null;
+			}	
 		}
 		ReferenceBinding superType = (ReferenceBinding) receiverType;
 		if (superType.isTypeVariable()) {
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 21cb533..0e5b6be 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, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Fraunhofer FIRST - extended 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 ab3a87f..e957d28 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
@@ -131,7 +131,6 @@
 		for (int i = 0; i < varArgIndex; i++) {
 			arguments[i].generateCode(currentScope, codeStream, true);
 		}
-
 		ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type
 		ArrayBinding codeGenVarArgsType = (ArrayBinding) binding.parameters[varArgIndex].erasure();
 		int elementsTypeID = varArgsType.elementsType().id;
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 6fbfe22..b8dbadf 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -11,6 +11,8 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
+import java.util.Arrays;
+
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
@@ -32,11 +34,15 @@
 	public int blockStart;
 	public int caseCount;
 	int[] constants;
+	String[] stringConstants;
 
 	// fallthrough
 	public final static int CASE = 0;
 	public final static int FALLTHROUGH = 1;
 	public final static int ESCAPING = 2;
+	
+	// for switch on strings
+	private static final char[] SecretStringVariableName = " switchDispatchString".toCharArray(); //$NON-NLS-1$
 
 
 	public SyntheticMethodBinding synthetic; // use for switch on enums types
@@ -44,11 +50,16 @@
 	// for local variables table attributes
 	int preSwitchInitStateIndex = -1;
 	int mergedInitStateIndex = -1;
+	
+	CaseStatement[] duplicateCaseStatements = null;
+	int duplicateCaseStatementsCounter = 0;
+	private LocalVariableBinding dispatchStringCopy = null;
 
 	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
 		try {
 			flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
-			if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
+			if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0
+					|| (this.expression.resolvedType != null && this.expression.resolvedType.id == T_JavaLangString)) {
 				this.expression.checkNPE(currentScope, flowContext, flowInfo);
 			}
 			SwitchFlowContext switchContext =
@@ -121,13 +132,182 @@
 	}
 
 	/**
+	 * Switch on String code generation
+	 * This assumes that hashCode() specification for java.lang.String is API
+	 * and is stable.
+	 * @see "http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html"
+	 * @see "http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/String.html"
+	 *
+	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
+	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+	 */
+	public void generateCodeForStringSwitch(BlockScope currentScope, CodeStream codeStream) {
+
+		try {
+			if ((this.bits & IsReachable) == 0) {
+				return;
+			}
+			int pc = codeStream.position;
+			
+			class StringSwitchCase implements Comparable {
+				int hashCode;
+				String string;
+				BranchLabel label;
+				public StringSwitchCase(int hashCode, String string, BranchLabel label) {
+					this.hashCode = hashCode;
+					this.string = string;
+					this.label = label;
+				}
+				public int compareTo(Object o) {
+					StringSwitchCase that = (StringSwitchCase) o;
+					if (this.hashCode == that.hashCode) {
+						return 0;
+					}
+					if (this.hashCode > that.hashCode) {
+						return 1;
+					}
+					return -1;
+				}
+				public String toString() {
+					return "StringSwitchCase :\n" + //$NON-NLS-1$
+					       "case " + this.hashCode + ":(" + this.string + ")\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$	       
+				}
+			}
+
+			final boolean hasCases = this.caseCount != 0;
+			final boolean valueRequired = this.expression.constant == Constant.NotAConstant || hasCases;
+
+			StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code.
+			BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount];
+			CaseLabel [] hashCodeCaseLabels = new CaseLabel[this.caseCount];
+			this.constants = new int[this.caseCount];  // hashCode() values.
+			for (int i = 0, max = this.caseCount; i < max; i++) {
+				this.cases[i].targetLabel = (sourceCaseLabels[i] = new BranchLabel(codeStream));  // A branch label, not a case label.
+				sourceCaseLabels[i].tagBits |= BranchLabel.USED;
+				stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[i]);
+				hashCodeCaseLabels[i] = new CaseLabel(codeStream);
+				hashCodeCaseLabels[i].tagBits |= BranchLabel.USED;
+				
+			}
+			Arrays.sort(stringCases);
+
+			int uniqHashCount = 0;
+			int lastHashCode = 0; 
+			for (int i = 0, length = this.caseCount; i < length; ++i) {
+				int hashCode = stringCases[i].hashCode;
+				if (i == 0 || hashCode != lastHashCode) {
+					lastHashCode = this.constants[uniqHashCount++] = hashCode;
+				}
+			}
+				
+			if (uniqHashCount != this.caseCount) { // multiple keys hashed to the same value.
+				System.arraycopy(this.constants, 0, this.constants = new int[uniqHashCount], 0, uniqHashCount);
+				System.arraycopy(hashCodeCaseLabels, 0, hashCodeCaseLabels = new CaseLabel[uniqHashCount], 0, uniqHashCount);
+			}
+			int[] sortedIndexes = new int[uniqHashCount]; // hash code are sorted already anyways.
+			for (int i = 0; i < uniqHashCount; i++) {
+				sortedIndexes[i] = i;
+			}
+
+			CaseLabel defaultCaseLabel = new CaseLabel(codeStream);
+			defaultCaseLabel.tagBits |= BranchLabel.USED;
+
+			// prepare the labels and constants
+			this.breakLabel.initialize(codeStream);
+			
+			BranchLabel defaultBranchLabel = new BranchLabel(codeStream);
+			if (hasCases) defaultBranchLabel.tagBits |= BranchLabel.USED;
+			if (this.defaultCase != null) {
+				this.defaultCase.targetLabel = defaultBranchLabel;
+			}
+			// generate expression
+			this.expression.generateCode(currentScope, codeStream, true);
+			codeStream.store(this.dispatchStringCopy, true);  // leaves string on operand stack
+			codeStream.addVariable(this.dispatchStringCopy);
+			codeStream.invokeStringHashCode();
+			if (hasCases) {
+				codeStream.lookupswitch(defaultCaseLabel, this.constants, sortedIndexes, hashCodeCaseLabels);
+				for (int i = 0, j = 0, max = this.caseCount; i < max; i++) {
+					int hashCode = stringCases[i].hashCode;
+					if (i == 0 || hashCode != lastHashCode) {
+						lastHashCode = hashCode;
+						if (i != 0) {
+							codeStream.goto_(defaultBranchLabel);
+						}
+						hashCodeCaseLabels[j++].place();
+					}
+					codeStream.load(this.dispatchStringCopy);
+					codeStream.ldc(stringCases[i].string);
+					codeStream.invokeStringEquals();
+					codeStream.ifne(stringCases[i].label);
+				}
+				codeStream.goto_(defaultBranchLabel);
+			} else if (valueRequired) {
+				codeStream.pop();
+			}
+
+			// generate the switch block statements
+			int caseIndex = 0;
+			if (this.statements != null) {
+				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.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block
+						if (this.preSwitchInitStateIndex != -1) {
+							codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+						}
+						caseIndex++;
+					} else {
+						if (statement == this.defaultCase) { // statements[i] is a case or a default case
+							defaultCaseLabel.place(); // branch label gets placed by generateCode below.
+							this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
+							if (this.preSwitchInitStateIndex != -1) {
+								codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+							}
+						}
+					}
+					statement.generateCode(this.scope, codeStream);
+				}
+			}
+			
+			// May loose some local variable initializations : affecting the local variable attributes
+			if (this.mergedInitStateIndex != -1) {
+				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+				codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
+			}
+			codeStream.removeVariable(this.dispatchStringCopy);
+			if (this.scope != currentScope) {
+				codeStream.exitUserScope(this.scope);
+			}
+			// place the trailing labels (for break and default case)
+			this.breakLabel.place();
+			if (this.defaultCase == null) {
+				// we want to force an line number entry to get an end position after the switch statement
+				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true);
+				defaultCaseLabel.place();
+				defaultBranchLabel.place();
+			}
+			codeStream.recordPositionsFrom(pc, this.sourceStart);
+		} catch (Throwable e) {
+			e.printStackTrace();
+		}
+		finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
+	}
+
+	
+	/**
 	 * Switch code generation
 	 *
 	 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
 	 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 	 */
 	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
-
+		if (this.expression.resolvedType.id == TypeIds.T_JavaLangString) {
+			generateCodeForStringSwitch(currentScope, codeStream);
+			return;
+		}
 		try {
 			if ((this.bits & IsReachable) == 0) {
 				return;
@@ -267,6 +447,7 @@
 	public void resolve(BlockScope upperScope) {
 		try {
 			boolean isEnumSwitch = false;
+			boolean isStringSwitch = false;
 			TypeBinding expressionType = this.expression.resolveType(upperScope);
 			if (expressionType != null) {
 				this.expression.computeConversion(upperScope, expressionType, expressionType);
@@ -285,6 +466,9 @@
 					} else if (upperScope.isBoxingCompatibleWith(expressionType, TypeBinding.INT)) {
 						this.expression.computeConversion(upperScope, TypeBinding.INT, expressionType);
 						break checkType;
+					} else if (upperScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_7 && expressionType.id == TypeIds.T_JavaLangString) {
+						isStringSwitch = true;
+						break checkType;
 					}
 					upperScope.problemReporter().incorrectSwitchType(this.expression, expressionType);
 					expressionType = null; // fault-tolerance: ignore type mismatch from constants from hereon
@@ -295,51 +479,55 @@
 				int length;
 				// collection of cases is too big but we will only iterate until caseCount
 				this.cases = new CaseStatement[length = this.statements.length];
-				this.constants = new int[length];
-				CaseStatement[] duplicateCaseStatements = null;
-				int duplicateCaseStatementsCounter = 0;
+				if (!isStringSwitch) {
+					this.constants = new int[length];
+				} else {
+					this.stringConstants = new String[length];
+				}
 				int counter = 0;
 				for (int i = 0; i < length; i++) {
 					Constant constant;
 					final Statement statement = this.statements[i];
 					if ((constant = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstant) {
-						int key = constant.intValue();
-						//----check for duplicate case statement------------
-						for (int j = 0; j < counter; j++) {
-							if (this.constants[j] == key) {
-								final CaseStatement currentCaseStatement = (CaseStatement) statement;
-								if (duplicateCaseStatements == null) {
-									this.scope.problemReporter().duplicateCase(this.cases[j]);
-									this.scope.problemReporter().duplicateCase(currentCaseStatement);
-									duplicateCaseStatements = new CaseStatement[length];
-									duplicateCaseStatements[duplicateCaseStatementsCounter++] = this.cases[j];
-									duplicateCaseStatements[duplicateCaseStatementsCounter++] = currentCaseStatement;
-								} else {
-									boolean found = false;
-									searchReportedDuplicate: for (int k = 2; k < duplicateCaseStatementsCounter; k++) {
-										if (duplicateCaseStatements[k] == statement) {
-											found = true;
-											break searchReportedDuplicate;
-										}
-									}
-									if (!found) {
-										this.scope.problemReporter().duplicateCase(currentCaseStatement);
-										duplicateCaseStatements[duplicateCaseStatementsCounter++] = currentCaseStatement;
-									}
+						if (!isStringSwitch) {
+							int key = constant.intValue();
+							//----check for duplicate case statement------------
+							for (int j = 0; j < counter; j++) {
+								if (this.constants[j] == key) {
+									reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
 								}
 							}
+							this.constants[counter++] = key;
+						} else {
+							String key = constant.stringValue();
+							//----check for duplicate case statement------------
+							for (int j = 0; j < counter; j++) {
+								if (this.stringConstants[j].equals(key)) {
+									reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+								}
+							}
+							this.stringConstants[counter++] = key;			
 						}
-						this.constants[counter++] = key;
 					}
 				}
 				if (length != counter) { // resize constants array
-					System.arraycopy(this.constants, 0, this.constants = new int[counter], 0, counter);
+					if (!isStringSwitch) {
+						System.arraycopy(this.constants, 0, this.constants = new int[counter], 0, counter);
+					} else {
+						System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter], 0, counter);
+					}
 				}
 			} else {
 				if ((this.bits & UndocumentedEmptyBlock) != 0) {
 					upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd);
 				}
 			}
+			if (isStringSwitch) {
+				this.dispatchStringCopy  = new LocalVariableBinding(SecretStringVariableName, upperScope.getJavaLangString(), ClassFileConstants.AccDefault, false);
+				upperScope.addLocalVariable(this.dispatchStringCopy);
+				this.dispatchStringCopy.setConstant(Constant.NotAConstant);
+				this.dispatchStringCopy.useFlag = LocalVariableBinding.USED;
+			}
 			// for enum switch, check if all constants are accounted for (if no default)
 			if (isEnumSwitch && this.defaultCase == null
 					&& upperScope.compilerOptions().getSeverity(CompilerOptions.IncompleteEnumSwitch) != ProblemSeverities.Ignore) {
@@ -366,6 +554,28 @@
 		}
 	}
 
+	private void reportDuplicateCase(final CaseStatement duplicate, final CaseStatement original, int length) {
+		if (this.duplicateCaseStatements == null) {
+			this.scope.problemReporter().duplicateCase(original);
+			this.scope.problemReporter().duplicateCase(duplicate);
+			this.duplicateCaseStatements = new CaseStatement[length];
+			this.duplicateCaseStatements[this.duplicateCaseStatementsCounter++] = original;
+			this.duplicateCaseStatements[this.duplicateCaseStatementsCounter++] = duplicate;
+		} else {
+			boolean found = false;
+			searchReportedDuplicate: for (int k = 2; k < this.duplicateCaseStatementsCounter; k++) {
+				if (this.duplicateCaseStatements[k] == duplicate) {
+					found = true;
+					break searchReportedDuplicate;
+				}
+			}
+			if (!found) {
+				this.scope.problemReporter().duplicateCase(duplicate);
+				this.duplicateCaseStatements[this.duplicateCaseStatementsCounter++] = duplicate;
+			}
+		}
+	}
+
 	public void traverse(
 			ASTVisitor visitor,
 			BlockScope blockScope) {
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 af3b33f..b794429 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
@@ -13,6 +13,7 @@
  *******************************************************************************/
 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.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.*;
@@ -26,9 +27,14 @@
  */
 public class TryStatement extends SubRoutineStatement {
 
-	private final static char[] SECRET_RETURN_ADDRESS_NAME = " returnAddress".toCharArray(); //$NON-NLS-1$
-	private final static char[] SECRET_ANY_HANDLER_NAME = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$
-	private final static char[] SECRET_RETURN_VALUE_NAME = " returnValue".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_RETURN_ADDRESS_NAME = " returnAddress".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_ANY_HANDLER_NAME = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_PRIMARY_EXCEPTION_VARIABLE_NAME = " primaryException".toCharArray(); //$NON-NLS-1$
+	static final char[] SECRET_CAUGHT_THROWABLE_VARIABLE_NAME = " caughtThrowable".toCharArray(); //$NON-NLS-1$;
+	static final char[] SECRET_RETURN_VALUE_NAME = " returnValue".toCharArray(); //$NON-NLS-1$
+
+	private static LocalDeclaration [] NO_RESOURCES = new LocalDeclaration[0];
+	public LocalDeclaration[] resources = NO_RESOURCES;
 
 	public Block tryBlock;
 	public Block[] catchBlocks;
@@ -60,16 +66,20 @@
 	private int[] reusableJSRStateIndexes;
 	private int reusableJSRTargetsCount = 0;
 
-	private final static int NO_FINALLY = 0;										// no finally block
-	private final static int FINALLY_SUBROUTINE = 1; 					// finally is generated as a subroutine (using jsr/ret bytecodes)
-	private final static int FINALLY_DOES_NOT_COMPLETE = 2;		// non returning finally is optimized with only one instance of finally block
-	private final static int FINALLY_INLINE = 3;								// finally block must be inlined since cannot use jsr/ret bytecodes >1.5
+	private static final int NO_FINALLY = 0;										// no finally block
+	private static final int FINALLY_SUBROUTINE = 1; 					// finally is generated as a subroutine (using jsr/ret bytecodes)
+	private static final int FINALLY_DOES_NOT_COMPLETE = 2;		// non returning finally is optimized with only one instance of finally block
+	private static final int FINALLY_INLINE = 3;								// finally block must be inlined since cannot use jsr/ret bytecodes >1.5
 
 	// for local variables table attributes
 	int mergedInitStateIndex = -1;
 	int preTryInitStateIndex = -1;
 	int naturalExitMergeInitStateIndex = -1;
 	int[] catchExitInitStateIndexes;
+	private LocalVariableBinding primaryExceptionVariable;
+	private LocalVariableBinding caughtThrowableVariable;
+	private ExceptionLabel[] resourceExceptionLabels;
+	private int[] caughtExceptionsCatchBlocks;
 
 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
 
@@ -86,6 +96,12 @@
 	if (this.anyExceptionVariable != null) {
 		this.anyExceptionVariable.useFlag = LocalVariableBinding.USED;
 	}
+	if (this.primaryExceptionVariable != null) {
+		this.primaryExceptionVariable.useFlag = LocalVariableBinding.USED;
+	}
+	if (this.caughtThrowableVariable != null) {
+		this.caughtThrowableVariable.useFlag = LocalVariableBinding.USED;
+	}
 	if (this.returnAddressVariable != null) { // TODO (philippe) if subroutine is escaping, unused
 		this.returnAddressVariable.useFlag = LocalVariableBinding.USED;
 	}
@@ -100,6 +116,8 @@
 				flowContext,
 				this,
 				this.caughtExceptionTypes,
+				this.caughtExceptionsCatchBlocks,
+				this.catchArguments,
 				null,
 				this.scope,
 				flowInfo.unconditionalInits());
@@ -110,6 +128,21 @@
 		// only try blocks initialize that member - may consider creating a
 		// separate class if needed
 
+		for (int i = 0, max = this.resources.length; i < max; i++) {
+			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
+			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+			TypeBinding type = this.resources[i].binding.type;
+			if (type != null && type.isValidBinding()) {
+				ReferenceBinding binding = (ReferenceBinding) type;
+				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
+				if (closeMethod != null && closeMethod.returnType.id == TypeIds.T_void) {
+					ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions;
+					for (int j = 0, length = thrownExceptions.length; j < length; j++) {
+						handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[i], flowInfo, currentScope, true);
+					}
+				}
+			}
+		}
 		FlowInfo tryInfo;
 		if (this.tryBlock.isEmptyBlock()) {
 			tryInfo = flowInfo;
@@ -130,18 +163,17 @@
 			for (int i = 0; i < catchCount; i++) {
 				// keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis)
 				FlowInfo catchInfo;
-				if (this.caughtExceptionTypes[i].isUncheckedException(true)) {
+				if (isUncheckedCatchBlock(i)) {
 					catchInfo =
 						handlingContext.initsOnFinally.mitigateNullInfoOf(
 							flowInfo.unconditionalCopy().
 								addPotentialInitializationsFrom(
-									handlingContext.initsOnException(
-										this.caughtExceptionTypes[i])).
+									handlingContext.initsOnException(i)).
 								addPotentialInitializationsFrom(tryInfo).
 								addPotentialInitializationsFrom(
 									handlingContext.initsOnReturn));
 				} else {
-					FlowInfo initsOnException = handlingContext.initsOnException(this.caughtExceptionTypes[i]);
+					FlowInfo initsOnException = handlingContext.initsOnException(i);
 					catchInfo =
 						flowInfo.nullInfoLessUnconditionalCopy()
 							.addPotentialInitializationsFrom(initsOnException)
@@ -163,7 +195,7 @@
 				"(uncheckedExceptionTypes notNil and: [uncheckedExceptionTypes at: index])
 				ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
 				*/
-				if (this.tryBlock.statements == null) {
+				if (this.tryBlock.statements == null && this.resources == NO_RESOURCES) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350579
 					catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 				catchInfo =
@@ -211,6 +243,8 @@
 				insideSubContext,
 				this,
 				this.caughtExceptionTypes,
+				this.caughtExceptionsCatchBlocks,
+				this.catchArguments,
 				null,
 				this.scope,
 				flowInfo.unconditionalInits());
@@ -219,6 +253,21 @@
 		// only try blocks initialize that member - may consider creating a
 		// separate class if needed
 
+		for (int i = 0, max = this.resources.length; i < max; i++) {
+			flowInfo = this.resources[i].analyseCode(currentScope, handlingContext, flowInfo.copy());
+			this.resources[i].binding.useFlag = LocalVariableBinding.USED; // Is implicitly used anyways.
+			TypeBinding type = this.resources[i].binding.type;
+			if (type != null && type.isValidBinding()) {
+				ReferenceBinding binding = (ReferenceBinding) type;
+				MethodBinding closeMethod = binding.getExactMethod(ConstantPool.Close, new TypeBinding [0], this.scope.compilationUnitScope()); // scope needs to be tighter
+				if (closeMethod != null && closeMethod.returnType.id == TypeIds.T_void) {
+					ReferenceBinding[] thrownExceptions = closeMethod.thrownExceptions;
+					for (int j = 0, length = thrownExceptions.length; j < length; j++) {
+						handlingContext.checkExceptionHandlers(thrownExceptions[j], this.resources[j], flowInfo, currentScope);
+					}
+				}
+			}
+		}
 		FlowInfo tryInfo;
 		if (this.tryBlock.isEmptyBlock()) {
 			tryInfo = flowInfo;
@@ -239,18 +288,17 @@
 			for (int i = 0; i < catchCount; i++) {
 				// keep track of the inits that could potentially have led to this exception handler (for final assignments diagnosis)
 				FlowInfo catchInfo;
-				if (this.caughtExceptionTypes[i].isUncheckedException(true)) {
+				if (isUncheckedCatchBlock(i)) {
 					catchInfo =
 						handlingContext.initsOnFinally.mitigateNullInfoOf(
 							flowInfo.unconditionalCopy().
 								addPotentialInitializationsFrom(
-									handlingContext.initsOnException(
-										this.caughtExceptionTypes[i])).
+									handlingContext.initsOnException(i)).
 								addPotentialInitializationsFrom(tryInfo).
 								addPotentialInitializationsFrom(
 									handlingContext.initsOnReturn));
 				}else {
-					FlowInfo initsOnException = handlingContext.initsOnException(this.caughtExceptionTypes[i]);
+					FlowInfo initsOnException = handlingContext.initsOnException(i);
 					catchInfo =
 						flowInfo.nullInfoLessUnconditionalCopy()
 							.addPotentialInitializationsFrom(initsOnException)
@@ -272,7 +320,7 @@
 				"(uncheckedExceptionTypes notNil and: [uncheckedExceptionTypes at: index])
 				ifTrue: [catchInits addPotentialInitializationsFrom: tryInits]."
 				*/
-				if (this.tryBlock.statements == null) {
+				if (this.tryBlock.statements == null && this.resources == NO_RESOURCES) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350579
 					catchInfo.setReachMode(FlowInfo.UNREACHABLE_OR_DEAD);
 				}
 				catchInfo =
@@ -321,12 +369,14 @@
 //{ObjectTeams: new hook for guard predicate analysis:
 protected ExceptionHandlingFlowContext createFlowContext(FlowContext flowContext, FlowInfo flowInfo) {
 	return new ExceptionHandlingFlowContext(
-				flowContext,
-				this,
-				this.caughtExceptionTypes,
-				null, // initialization parent
-				this.scope,
-				flowInfo.unconditionalInits());
+			flowContext,
+			this,
+			this.caughtExceptionTypes,
+			this.caughtExceptionsCatchBlocks,
+			this.catchArguments,
+			null,
+			this.scope,
+			flowInfo.unconditionalInits());
 }
 // SH}
 public ExceptionLabel enterAnyExceptionHandler(CodeStream codeStream) {
@@ -340,6 +390,20 @@
 		this.declaredExceptionLabels[i].placeStart();
 	}
 }
+//Return true if the catch block corresponds to an unchecked exception making allowance for multi-catch blocks.
+private boolean isUncheckedCatchBlock(int catchBlock) {
+	if (this.caughtExceptionsCatchBlocks == null) {
+		return this.caughtExceptionTypes[catchBlock].isUncheckedException(true);
+	}
+	for (int i = 0, length = this.caughtExceptionsCatchBlocks.length; i < length; i++) {
+		if (this.caughtExceptionsCatchBlocks[i] == catchBlock) {
+			if (this.caughtExceptionTypes[i].isUncheckedException(true)) {
+				return true;
+			}
+		}
+	}
+	return false;
+}
 
 public void exitAnyExceptionHandler() {
 	if (this.subRoutineStartLabel == null)
@@ -391,7 +455,15 @@
 	if (maxCatches > 0) {
 		exceptionLabels = new ExceptionLabel[maxCatches];
 		for (int i = 0; i < maxCatches; i++) {
-			ExceptionLabel exceptionLabel = new ExceptionLabel(codeStream, this.catchArguments[i].binding.type);
+			Argument argument = this.catchArguments[i];
+			ExceptionLabel exceptionLabel = null;
+			if ((argument.binding.tagBits & TagBits.MultiCatchParameter) != 0) {
+				MultiCatchExceptionLabel multiCatchExceptionLabel = new MultiCatchExceptionLabel(codeStream, argument.binding.type);
+				multiCatchExceptionLabel.initialize((UnionTypeReference) argument.type);
+				exceptionLabel = multiCatchExceptionLabel;
+			} else {
+				exceptionLabel = new ExceptionLabel(codeStream, argument.binding.type);
+			}
 			exceptionLabel.placeStart();
 			exceptionLabels[i] = exceptionLabel;
 		}
@@ -405,7 +477,85 @@
 	// generate the try block
 	try {
 		this.declaredExceptionLabels = exceptionLabels;
+		int resourceCount = this.resources.length;
+		if (resourceCount > 0) {
+			// Please see https://bugs.eclipse.org/bugs/show_bug.cgi?id=338402#c16
+			this.resourceExceptionLabels = new ExceptionLabel[resourceCount + 1];
+			codeStream.aconst_null();
+			codeStream.store(this.primaryExceptionVariable, false /* value not required */);
+			codeStream.addVariable(this.primaryExceptionVariable);
+			codeStream.aconst_null();
+			codeStream.store(this.caughtThrowableVariable, false /* value not required */);
+			codeStream.addVariable(this.caughtThrowableVariable);
+			for (int i = 0; i <= resourceCount; i++) {
+				this.resourceExceptionLabels[i] = new ExceptionLabel(codeStream, this.scope.getJavaLangThrowable());
+				this.resourceExceptionLabels[i].placeStart();
+				if (i < resourceCount) {
+					this.resources[i].generateCode(this.scope, codeStream); // Initialize resources ...
+				}
+			}
+		}
 		this.tryBlock.generateCode(this.scope, codeStream);
+		if (resourceCount > 0) {
+			for (int i = resourceCount; i >= 0; i--) {
+				BranchLabel exitLabel = new BranchLabel(codeStream);
+				this.resourceExceptionLabels[i].placeEnd(); // outer handler if any is the one that should catch exceptions out of close()
+				
+				LocalVariableBinding localVariable = i > 0 ? this.resources[i-1].binding : null;
+				if ((this.bits & ASTNode.IsTryBlockExiting) == 0) {
+					// inline resource closure
+					if (i > 0) {
+						int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785
+						codeStream.load(localVariable);
+				    	codeStream.ifnull(exitLabel);
+				    	codeStream.load(localVariable);
+				    	codeStream.invokeAutoCloseableClose(localVariable.type);
+				    	codeStream.recordPositionsFrom(invokeCloseStartPc, this.tryBlock.sourceEnd);	
+				    }
+					codeStream.goto_(exitLabel); // skip over the catch block.
+				}
+				codeStream.pushExceptionOnStack(this.scope.getJavaLangThrowable());
+				this.resourceExceptionLabels[i].place();
+				if (i == resourceCount) { 
+					// inner most try's catch/finally can be a lot simpler. 
+					codeStream.store(this.primaryExceptionVariable, false);
+					// fall through, invoke close() and re-throw.
+				} else {
+					BranchLabel elseLabel = new BranchLabel(codeStream), postElseLabel = new BranchLabel(codeStream);
+					codeStream.store(this.caughtThrowableVariable, false);
+					codeStream.load(this.primaryExceptionVariable);
+					codeStream.ifnonnull(elseLabel);
+					codeStream.load(this.caughtThrowableVariable);
+					codeStream.store(this.primaryExceptionVariable, false);
+					codeStream.goto_(postElseLabel);
+					elseLabel.place();
+					codeStream.load(this.primaryExceptionVariable);
+					codeStream.load(this.caughtThrowableVariable);
+					codeStream.if_acmpeq(postElseLabel);
+					codeStream.load(this.primaryExceptionVariable);
+					codeStream.load(this.caughtThrowableVariable);
+					codeStream.invokeThrowableAddSuppressed();
+					postElseLabel.place();
+				}
+				if (i > 0) {
+					// inline resource close here rather than bracketing the current catch block with a try region.
+					BranchLabel postCloseLabel = new BranchLabel(codeStream);
+					int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785			
+					codeStream.load(localVariable);
+					codeStream.ifnull(postCloseLabel);
+					codeStream.load(localVariable);
+					codeStream.invokeAutoCloseableClose(localVariable.type);
+					codeStream.recordPositionsFrom(invokeCloseStartPc, this.tryBlock.sourceEnd);
+					codeStream.removeVariable(localVariable);
+					postCloseLabel.place();
+				}
+				codeStream.load(this.primaryExceptionVariable);
+				codeStream.athrow();
+				exitLabel.place();
+			}
+			codeStream.removeVariable(this.primaryExceptionVariable);
+			codeStream.removeVariable(this.caughtThrowableVariable);
+		}
 	} finally {
 		this.declaredExceptionLabels = null;
 	}
@@ -460,7 +610,7 @@
 				 * we also don't generate the corresponding catch block, otherwise we have some
 				 * unreachable bytecodes
 				 */
-				if (exceptionLabels[i].count == 0) continue;
+				if (exceptionLabels[i].getCount() == 0) continue;
 				enterAnyExceptionHandler(codeStream);
 				// May loose some local variable initializations : affecting the local variable attributes
 				if (this.preTryInitStateIndex != -1) {
@@ -527,7 +677,7 @@
 		// addition of a special handler so as to ensure that any uncaught exception (or exception thrown
 		// inside catch blocks) will run the finally block
 		int finallySequenceStartPC = codeStream.position;
-		if (this.subRoutineStartLabel != null && this.anyExceptionLabel.count != 0) {
+		if (this.subRoutineStartLabel != null && this.anyExceptionLabel.getCount() != 0) {
 			codeStream.pushExceptionOnStack(this.scope.getJavaLangThrowable());
 			if (this.preTryInitStateIndex != -1) {
 				// reset initialization state, as for a normal catch block
@@ -656,6 +806,27 @@
  */
 public boolean generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream, Object targetLocation, int stateIndex, LocalVariableBinding secretLocal) {
 
+	int resourceCount = this.resources.length;
+	if (resourceCount > 0) {
+		for (int i = resourceCount; i > 0; --i) {
+			// Disarm the handlers and take care of resource closure.
+			this.resourceExceptionLabels[i].placeEnd();
+			LocalVariableBinding localVariable = this.resources[i-1].binding;
+			BranchLabel exitLabel = new BranchLabel(codeStream);
+			int invokeCloseStartPc = codeStream.position; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343785
+			codeStream.load(localVariable);
+			codeStream.ifnull(exitLabel);
+			codeStream.load(localVariable);
+			codeStream.invokeAutoCloseableClose(localVariable.type);
+			codeStream.recordPositionsFrom(invokeCloseStartPc, this.tryBlock.sourceEnd);
+			exitLabel.place();
+		}
+		// Reinstall handlers
+		for (int i = resourceCount; i > 0; --i) {
+			this.resourceExceptionLabels[i].placeStart();
+		}
+	}
+
 	boolean isStackMapFrameCodeStream = codeStream instanceof StackMapFrameCodeStream;
 	int finallyMode = finallyMode();
 	switch(finallyMode) {
@@ -714,17 +885,6 @@
 	if (finallyMode == FINALLY_INLINE) {
 		if (isStackMapFrameCodeStream) {
 			((StackMapFrameCodeStream) codeStream).pushStateIndex(stateIndex);
-			if (this.naturalExitMergeInitStateIndex != -1 || stateIndex != -1) {
-				// reset initialization state, as for a normal catch block
-				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
-				codeStream.addDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
-			}
-		} else {
-			if (this.naturalExitMergeInitStateIndex != -1) {
-				// reset initialization state, as for a normal catch block
-				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
-				codeStream.addDefinitelyAssignedVariables(currentScope, this.naturalExitMergeInitStateIndex);
-			}
 		}
 		if (secretLocal != null) {
 			codeStream.addVariable(secretLocal);
@@ -750,7 +910,18 @@
 }
 
 public StringBuffer printStatement(int indent, StringBuffer output) {
-	printIndent(indent, output).append("try \n"); //$NON-NLS-1$
+	int length = this.resources.length;
+	printIndent(indent, output).append("try" + (length == 0 ? "\n" : " (")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+	for (int i = 0; i < length; i++) {
+		this.resources[i].printAsExpression(0, output);
+		if (i != length - 1) {
+			output.append(";\n"); //$NON-NLS-1$
+			printIndent(indent + 2, output);
+		}
+	}
+	if (length > 0) {
+		output.append(")\n"); //$NON-NLS-1$
+	}
 	this.tryBlock.printStatement(indent + 1, output);
 
 	//catches
@@ -758,7 +929,7 @@
 		for (int i = 0; i < this.catchBlocks.length; i++) {
 				output.append('\n');
 				printIndent(indent, output).append("catch ("); //$NON-NLS-1$
-				this.catchArguments[i].print(0, output).append(") "); //$NON-NLS-1$
+				this.catchArguments[i].print(0, output).append(")\n"); //$NON-NLS-1$
 				this.catchBlocks[i].printStatement(indent + 1, output);
 		}
 	//finally
@@ -774,8 +945,39 @@
 	// special scope for secret locals optimization.
 	this.scope = new BlockScope(upperScope);
 
-	BlockScope tryScope = new BlockScope(this.scope);
 	BlockScope finallyScope = null;
+    BlockScope resourceManagementScope = null; // Single scope to hold all resources and additional secret variables.
+	int resourceCount = this.resources.length;
+	if (resourceCount > 0) {
+		resourceManagementScope = new BlockScope(this.scope);
+		this.primaryExceptionVariable =
+			new LocalVariableBinding(TryStatement.SECRET_PRIMARY_EXCEPTION_VARIABLE_NAME, this.scope.getJavaLangThrowable(), ClassFileConstants.AccDefault, false);
+		resourceManagementScope.addLocalVariable(this.primaryExceptionVariable);
+		this.primaryExceptionVariable.setConstant(Constant.NotAConstant); // not inlinable
+		this.caughtThrowableVariable =
+			new LocalVariableBinding(TryStatement.SECRET_CAUGHT_THROWABLE_VARIABLE_NAME, this.scope.getJavaLangThrowable(), ClassFileConstants.AccDefault, false);
+		resourceManagementScope.addLocalVariable(this.caughtThrowableVariable);
+		this.caughtThrowableVariable.setConstant(Constant.NotAConstant); // not inlinable
+	}
+	for (int i = 0; i < resourceCount; i++) {
+		this.resources[i].resolve(resourceManagementScope);
+		LocalVariableBinding localVariableBinding = this.resources[i].binding;
+		if (localVariableBinding != null && localVariableBinding.isValidBinding()) {
+			localVariableBinding.modifiers |= ClassFileConstants.AccFinal;
+			localVariableBinding.tagBits |= TagBits.IsResource;
+			TypeBinding resourceType = localVariableBinding.type;
+			if (resourceType instanceof ReferenceBinding) {
+				if (resourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangAutoCloseable, false /*AutoCloseable is not a class*/) == null && resourceType.isValidBinding()) {
+					upperScope.problemReporter().resourceHasToImplementAutoCloseable(resourceType, this.resources[i].type);
+					localVariableBinding.type = new ProblemReferenceBinding(CharOperation.splitOn('.', resourceType.shortReadableName()), null, ProblemReasons.InvalidTypeForAutoManagedResource);
+				}
+			} else if (resourceType != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=349862, avoid secondary error in problematic null case
+				upperScope.problemReporter().resourceHasToImplementAutoCloseable(resourceType, this.resources[i].type);
+				localVariableBinding.type = new ProblemReferenceBinding(CharOperation.splitOn('.', resourceType.shortReadableName()), null, ProblemReasons.InvalidTypeForAutoManagedResource);
+			}
+		}
+	}
+	BlockScope tryScope = new BlockScope(resourceManagementScope != null ? resourceManagementScope : this.scope);
 
 	if (this.finallyBlock != null) {
 		if (this.finallyBlock.isEmptyBlock()) {
@@ -821,7 +1023,8 @@
 			}
 			this.finallyBlock.resolveUsing(finallyScope);
 			// force the finally scope to have variable positions shifted after its try scope and catch ones
-			finallyScope.shiftScopes = new BlockScope[this.catchArguments == null ? 1 : this.catchArguments.length+1];
+			int shiftScopesLength = this.catchArguments == null ? 1 : this.catchArguments.length + 1;
+			finallyScope.shiftScopes = new BlockScope[shiftScopesLength];
 			finallyScope.shiftScopes[0] = tryScope;
 		}
 	}
@@ -831,6 +1034,7 @@
 	if (this.catchBlocks != null) {
 		int length = this.catchArguments.length;
 		TypeBinding[] argumentTypes = new TypeBinding[length];
+		boolean containsUnionTypes = false;
 		boolean catchHasError = false;
 		for (int i = 0; i < length; i++) {
 			BlockScope catchScope = new BlockScope(this.scope);
@@ -842,7 +1046,9 @@
 				DeclaredLifting.transformCatch(catchScope, this.catchBlocks[i], this.catchArguments[i]);
 // SH}
 			// side effect on catchScope in resolveForCatch(..)
-			if ((argumentTypes[i] = this.catchArguments[i].resolveForCatch(catchScope)) == null) {
+			Argument catchArgument = this.catchArguments[i];
+			containsUnionTypes |= (catchArgument.type.bits & ASTNode.IsUnionType) != 0;
+			if ((argumentTypes[i] = catchArgument.resolveForCatch(catchScope)) == null) {
 				catchHasError = true;
 			}
 			this.catchBlocks[i].resolveUsing(catchScope);
@@ -852,15 +1058,7 @@
 		}
 		// Verify that the catch clause are ordered in the right way:
 		// more specialized first.
-		this.caughtExceptionTypes = new ReferenceBinding[length];
-		for (int i = 0; i < length; i++) {
-			this.caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i];
-			for (int j = 0; j < i; j++) {
-				if (this.caughtExceptionTypes[i].isCompatibleWith(argumentTypes[j])) {
-					this.scope.problemReporter().wrongSequenceOfExceptionTypesError(this, this.caughtExceptionTypes[i], i, argumentTypes[j]);
-				}
-			}
-		}
+		verifyDuplicationAndOrder(length, argumentTypes, containsUnionTypes);
 	} else {
 		this.caughtExceptionTypes = new ReferenceBinding[0];
 	}
@@ -872,9 +1070,12 @@
 		this.scope.addSubscope(finallyScope);
 	}
 }
-
 public void traverse(ASTVisitor visitor, BlockScope blockScope) {
 	if (visitor.visit(this, blockScope)) {
+		LocalDeclaration[] localDeclarations = this.resources;
+		for (int i = 0, max = localDeclarations.length; i < max; i++) {
+			localDeclarations[i].traverse(visitor, this.scope);
+		}
 		this.tryBlock.traverse(visitor, this.scope);
 		if (this.catchArguments != null) {
 			for (int i = 0, max = this.catchBlocks.length; i < max; i++) {
@@ -887,4 +1088,70 @@
 	}
 	visitor.endVisit(this, blockScope);
 }
+protected void verifyDuplicationAndOrder(int length, TypeBinding[] argumentTypes, boolean containsUnionTypes) {
+	// Verify that the catch clause are ordered in the right way:
+	// more specialized first.
+	if (containsUnionTypes) {
+		int totalCount = 0;
+		ReferenceBinding[][] allExceptionTypes = new ReferenceBinding[length][];
+		for (int i = 0; i < length; i++) {
+			ReferenceBinding currentExceptionType = (ReferenceBinding) argumentTypes[i];
+			TypeReference catchArgumentType = this.catchArguments[i].type;
+			if ((catchArgumentType.bits & ASTNode.IsUnionType) != 0) {
+				TypeReference[] typeReferences = ((UnionTypeReference) catchArgumentType).typeReferences;
+				int typeReferencesLength = typeReferences.length;
+				ReferenceBinding[] unionExceptionTypes = new ReferenceBinding[typeReferencesLength];
+				for (int j = 0; j < typeReferencesLength; j++) {
+					unionExceptionTypes[j] = (ReferenceBinding) typeReferences[j].resolvedType;
+				}
+				totalCount += typeReferencesLength;
+				allExceptionTypes[i] = unionExceptionTypes;
+			} else {
+				allExceptionTypes[i] = new ReferenceBinding[] { currentExceptionType };
+				totalCount++;
+			}
+		}
+		this.caughtExceptionTypes = new ReferenceBinding[totalCount];
+		this.caughtExceptionsCatchBlocks  = new int[totalCount];
+		for (int i = 0, l = 0; i < length; i++) {
+			ReferenceBinding[] currentExceptions = allExceptionTypes[i];
+			loop: for (int j = 0, max = currentExceptions.length; j < max; j++) {
+				ReferenceBinding exception = currentExceptions[j];
+				this.caughtExceptionTypes[l] = exception;
+				this.caughtExceptionsCatchBlocks[l++] = i;
+				// now iterate over all previous exceptions
+				for (int k = 0; k < i; k++) {
+					ReferenceBinding[] exceptions = allExceptionTypes[k];
+					for (int n = 0, max2 = exceptions.length; n < max2; n++) {
+						ReferenceBinding currentException = exceptions[n];
+						if (exception.isCompatibleWith(currentException)) {
+							TypeReference catchArgumentType = this.catchArguments[i].type;
+							if ((catchArgumentType.bits & ASTNode.IsUnionType) != 0) {
+								catchArgumentType = ((UnionTypeReference) catchArgumentType).typeReferences[j];
+							}
+							this.scope.problemReporter().wrongSequenceOfExceptionTypesError(
+								catchArgumentType,
+								exception,
+								currentException);
+							break loop;
+						}
+					}
+				}
+			}
+		}
+	} else {
+		this.caughtExceptionTypes = new ReferenceBinding[length];
+		for (int i = 0; i < length; i++) {
+			this.caughtExceptionTypes[i] = (ReferenceBinding) argumentTypes[i];
+			for (int j = 0; j < i; j++) {
+				if (this.caughtExceptionTypes[i].isCompatibleWith(argumentTypes[j])) {
+					this.scope.problemReporter().wrongSequenceOfExceptionTypesError(
+						this.catchArguments[i].type,
+						this.caughtExceptionTypes[i],
+						argumentTypes[j]);
+				}
+			}
+		}
+	}
+}
 }
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 efeb51d..840b497 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, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -40,6 +40,8 @@
  */
 public abstract class TypeReference extends Expression {
 
+	public static final TypeReference[] NO_TYPE_ARGUMENTS = new TypeReference[0];
+
 //{ObjectTeams: for baseclass decapsulation (implement interface from Expression):
 private DecapsulationState baseclassDecapsulation = DecapsulationState.NONE;
 public void setBaseclassDecapsulation(DecapsulationState state) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnionTypeReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnionTypeReference.java
new file mode 100644
index 0000000..f1d7415
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/UnionTypeReference.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made 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.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;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class UnionTypeReference extends TypeReference {
+	public TypeReference[] typeReferences;
+
+	public UnionTypeReference(TypeReference[] typeReferences) {
+		this.bits |= ASTNode.IsUnionType;
+		this.typeReferences = typeReferences;
+		this.sourceStart = typeReferences[0].sourceStart;
+		int length = typeReferences.length;
+		this.sourceEnd = typeReferences[length - 1].sourceEnd;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#copyDims(int)
+	 */
+	public TypeReference copyDims(int dim) {
+		return this;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getLastToken()
+	 */
+	public char[] getLastToken() {
+		return null;
+	}
+
+	/**
+	 * @see org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	protected TypeBinding getTypeBinding(Scope scope) {
+		return null; // not supported here - combined with resolveType(...)
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.Scope)
+	 */
+	public TypeBinding resolveType(BlockScope scope, boolean checkBounds) {
+		// return the lub (least upper bound of all type binding) 
+		int length = this.typeReferences.length;
+		TypeBinding[] allExceptionTypes = new TypeBinding[length];
+		boolean hasError = false;
+		for (int i = 0; i < length; i++) {
+			TypeBinding exceptionType = this.typeReferences[i].resolveType(scope, checkBounds);
+			if (exceptionType == null) {
+				return null;
+			}
+			switch(exceptionType.kind()) {
+				case Binding.PARAMETERIZED_TYPE :
+					if (exceptionType.isBoundParameterizedType()) {
+						hasError = true;
+						scope.problemReporter().invalidParameterizedExceptionType(exceptionType, this.typeReferences[i]);
+						// fall thru to create the variable - avoids additional errors because the variable is missing
+					}
+					break;
+				case Binding.TYPE_PARAMETER :
+					scope.problemReporter().invalidTypeVariableAsException(exceptionType, this.typeReferences[i]);
+					hasError = true;
+					// fall thru to create the variable - avoids additional errors because the variable is missing
+					break;
+			}
+			if (exceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null
+					&& exceptionType.isValidBinding()) {
+				scope.problemReporter().cannotThrowType(this.typeReferences[i], exceptionType);
+				hasError = true;
+			}
+			allExceptionTypes[i] = exceptionType;
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=340486, ensure types are of union type.
+			for (int j = 0; j < i; j++) {
+				if (allExceptionTypes[j].isCompatibleWith(exceptionType)) {
+					scope.problemReporter().wrongSequenceOfExceptionTypes(
+							this.typeReferences[j],
+							allExceptionTypes[j],
+							exceptionType);
+					hasError = true;
+				} else if (exceptionType.isCompatibleWith(allExceptionTypes[j])) {
+					scope.problemReporter().wrongSequenceOfExceptionTypes(
+							this.typeReferences[i],
+							exceptionType,
+							allExceptionTypes[j]);
+					hasError = true;
+				}
+			}
+		}
+		if (hasError) {
+			return null;
+		}
+		// compute lub
+		return (this.resolvedType = scope.lowerUpperBound(allExceptionTypes));
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeReference#getTypeName()
+	 */
+	public char[][] getTypeName() {
+		// we need to keep a return value that is a char[][]
+		return this.typeReferences[0].getTypeName();
+	}
+
+	/* (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 scope) {
+		if (visitor.visit(this, scope)) {
+			int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+			for (int i = 0; i < length; i++) {
+				this.typeReferences[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	/* (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 scope) {
+		if (visitor.visit(this, scope)) {
+			int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+			for (int i = 0; i < length; i++) {
+				this.typeReferences[i].traverse(visitor, scope);
+			}
+		}
+		visitor.endVisit(this, scope);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jdt.internal.compiler.ast.Expression#printExpression(int, java.lang.StringBuffer)
+	 */
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		int length = this.typeReferences == null ? 0 : this.typeReferences.length;
+		printIndent(indent, output);
+		for (int i = 0; i < length; i++) {
+			this.typeReferences[i].printExpression(0, output);
+			if (i != length - 1) {
+				output.append(" | "); //$NON-NLS-1$
+			}
+		}
+		return output;
+	}
+
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java
index 13f27ee..d81ec1c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2010 BEA Systems, Inc.
+ * Copyright (c) 2005, 2011 BEA Systems, Inc.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -292,18 +292,18 @@
 					return currentOffset;
 				}
 				break;
+			case 23:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_SAFEVARARGS)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationSafeVarargs;
+					return currentOffset;
+				}
+				break;
 			case 29:
 				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_TARGET)) {
 					currentOffset += 2;
 					return readTargetValue(currentOffset);
 				}
 				break;
-			case 33:
-				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_DOCUMENTED)) {
-					this.standardAnnotationTagBits |= TagBits.AnnotationDocumented;
-					return currentOffset;
-				}
-				break;
 			case 32:
 				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTION)) {
 					currentOffset += 2;
@@ -314,6 +314,18 @@
 					return currentOffset;
 				}
 				break;
+			case 33:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_DOCUMENTED)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationDocumented;
+					return currentOffset;
+				}
+				break;
+			case 52:
+				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE)) {
+					this.standardAnnotationTagBits |= TagBits.AnnotationPolymorphicSignature;
+					return currentOffset;
+				}
+				break;
 		}
 	}
 	for (int i = 0; i < numberOfPairs; i++) {
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 7831fd9..927c272 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
@@ -4206,6 +4206,26 @@
 			ConstantPool.ITERATOR_SIGNATURE);
 }
 
+public void invokeAutoCloseableClose(TypeBinding resourceType) {
+	// invokevirtual/interface: <resourceType>.close()
+	invoke(
+			resourceType.isInterface() ? Opcodes.OPC_invokeinterface : Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			0, // returnTypeSize
+			resourceType.constantPoolName(), 
+			ConstantPool.Close, 
+			ConstantPool.CloseSignature);
+}
+
+public void invokeThrowableAddSuppressed() {
+	invoke(Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			0, // returnTypeSize
+			ConstantPool.JavaLangThrowableConstantPoolName,
+			ConstantPool.AddSuppressed, 
+			ConstantPool.AddSuppressedSignature);
+}
+
 public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
 	// invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
 	int receiverAndArgsSize;
@@ -4656,7 +4676,26 @@
 			ConstantPool.ToString,
 			ConstantPool.ToStringSignature);
 }
-
+public void invokeStringEquals() {
+	// invokevirtual: java.lang.String.equals()
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			2, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangStringConstantPoolName,
+			ConstantPool.Equals,
+			ConstantPool.EqualsSignature);
+}
+public void invokeStringHashCode() {
+	// invokevirtual: java.lang.String.hashCode()
+	invoke(
+			Opcodes.OPC_invokevirtual,
+			1, // receiverAndArgsSize
+			1, // return type size
+			ConstantPool.JavaLangStringConstantPoolName,
+			ConstantPool.HashCode,
+			ConstantPool.HashCodeSignature);
+}
 public void invokeStringIntern() {
 	// invokevirtual: java.lang.String.intern()
 	invoke(
@@ -4667,7 +4706,6 @@
 			ConstantPool.Intern,
 			ConstantPool.InternSignature);
 }
-
 public void invokeStringValueOf(int typeID) {
 	// invokestatic: java.lang.String.valueOf(argumentType)
 	char[] signature;
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 4a764cf..aca35f6 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -23,989 +23,1002 @@
  * This type is used to store all the constant pool entries.
  */
 public class ConstantPool implements ClassFileConstants, TypeIds {
-    public static final int DOUBLE_INITIAL_SIZE = 5;
-    public static final int FLOAT_INITIAL_SIZE = 3;
-    public static final int INT_INITIAL_SIZE = 248;
-    public static final int LONG_INITIAL_SIZE = 5;
-    public static final int UTF8_INITIAL_SIZE = 778;
-    public static final int STRING_INITIAL_SIZE = 761;
-    public static final int METHODS_AND_FIELDS_INITIAL_SIZE = 450;
-    public static final int CLASS_INITIAL_SIZE = 86;
-    public static final int NAMEANDTYPE_INITIAL_SIZE = 272;
-    public static final int CONSTANTPOOL_INITIAL_SIZE = 2000;
-    public static final int CONSTANTPOOL_GROW_SIZE = 6000;
-    protected DoubleCache doubleCache;
-    protected FloatCache floatCache;
-    protected IntegerCache intCache;
-    protected LongCache longCache;
-    public CharArrayCache UTF8Cache;
-    protected CharArrayCache stringCache;
-    protected HashtableOfObject methodsAndFieldsCache;
-    protected CharArrayCache classCache;
-    protected HashtableOfObject nameAndTypeCacheForFieldsAndMethods;
-    public byte[] poolContent;
-    public int currentIndex = 1;
-    public int currentOffset;
-    public int[] offsets;
+	public static final int DOUBLE_INITIAL_SIZE = 5;
+	public static final int FLOAT_INITIAL_SIZE = 3;
+	public static final int INT_INITIAL_SIZE = 248;
+	public static final int LONG_INITIAL_SIZE = 5;
+	public static final int UTF8_INITIAL_SIZE = 778;
+	public static final int STRING_INITIAL_SIZE = 761;
+	public static final int METHODS_AND_FIELDS_INITIAL_SIZE = 450;
+	public static final int CLASS_INITIAL_SIZE = 86;
+	public static final int NAMEANDTYPE_INITIAL_SIZE = 272;
+	public static final int CONSTANTPOOL_INITIAL_SIZE = 2000;
+	public static final int CONSTANTPOOL_GROW_SIZE = 6000;
+	protected DoubleCache doubleCache;
+	protected FloatCache floatCache;
+	protected IntegerCache intCache;
+	protected LongCache longCache;
+	public CharArrayCache UTF8Cache;
+	protected CharArrayCache stringCache;
+	protected HashtableOfObject methodsAndFieldsCache;
+	protected CharArrayCache classCache;
+	protected HashtableOfObject nameAndTypeCacheForFieldsAndMethods;
+	public byte[] poolContent;
+	public int currentIndex = 1;
+	public int currentOffset;
+	public int[] offsets;
 
-    public ClassFile classFile;
-    public static final char[] Append = "append".toCharArray(); //$NON-NLS-1$
-    public static final char[] ARRAY_NEWINSTANCE_NAME = "newInstance".toCharArray(); //$NON-NLS-1$
-    public static final char[] ARRAY_NEWINSTANCE_SIGNATURE = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] ArrayCopy = "arraycopy".toCharArray(); //$NON-NLS-1$
-    public static final char[] ArrayCopySignature = "(Ljava/lang/Object;ILjava/lang/Object;II)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
-    public static final char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] booleanBooleanSignature = "(Z)Ljava/lang/Boolean;".toCharArray(); //$NON-NLS-1$
-    public static final char[] BooleanConstrSignature = "(Z)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_NAME = "booleanValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE = "()Z".toCharArray(); //$NON-NLS-1$
-    public static final char[] byteByteSignature = "(B)Ljava/lang/Byte;".toCharArray(); //$NON-NLS-1$
-    public static final char[] ByteConstrSignature = "(B)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] BYTEVALUE_BYTE_METHOD_NAME = "byteValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] BYTEVALUE_BYTE_METHOD_SIGNATURE = "()B".toCharArray(); //$NON-NLS-1$
-    public static final char[] charCharacterSignature = "(C)Ljava/lang/Character;".toCharArray(); //$NON-NLS-1$
-    public static final char[] CharConstrSignature = "(C)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] CHARVALUE_CHARACTER_METHOD_NAME = "charValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] CHARVALUE_CHARACTER_METHOD_SIGNATURE = "()C".toCharArray(); //$NON-NLS-1$
-    public static final char[] Clinit = "<clinit>".toCharArray(); //$NON-NLS-1$
-    public static final char[] DefaultConstructorSignature = "()V".toCharArray(); //$NON-NLS-1$
-    public static final char[] ClinitSignature = DefaultConstructorSignature;
-    public static final char[] DesiredAssertionStatus = "desiredAssertionStatus".toCharArray(); //$NON-NLS-1$
-    public static final char[] DesiredAssertionStatusSignature = "()Z".toCharArray(); //$NON-NLS-1$
-    public static final char[] DoubleConstrSignature = "(D)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] doubleDoubleSignature = "(D)Ljava/lang/Double;".toCharArray(); //$NON-NLS-1$
-    public static final char[] DOUBLEVALUE_DOUBLE_METHOD_NAME = "doubleValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE = "()D".toCharArray(); //$NON-NLS-1$
-    public static final char[] Exit = "exit".toCharArray(); //$NON-NLS-1$
-    public static final char[] ExitIntSignature = "(I)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] FloatConstrSignature = "(F)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] floatFloatSignature = "(F)Ljava/lang/Float;".toCharArray(); //$NON-NLS-1$
-    public static final char[] FLOATVALUE_FLOAT_METHOD_NAME = "floatValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] FLOATVALUE_FLOAT_METHOD_SIGNATURE = "()F".toCharArray(); //$NON-NLS-1$
-    public static final char[] ForName = "forName".toCharArray(); //$NON-NLS-1$
-    public static final char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_BOOLEAN_METHOD_NAME = "getBoolean".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_BYTE_METHOD_NAME = "getByte".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;)B".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_CHAR_METHOD_NAME = "getChar".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;)C".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_DOUBLE_METHOD_NAME = "getDouble".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;)D".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_FLOAT_METHOD_NAME = "getFloat".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;)F".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_INT_METHOD_NAME = "getInt".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;)I".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_LONG_METHOD_NAME = "getLong".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;)J".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_OBJECT_METHOD_NAME = "get".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_SHORT_METHOD_NAME = "getShort".toCharArray(); //$NON-NLS-1$
-    public static final char[] GET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;)S".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetClass = "getClass".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetClassSignature = "()Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetComponentType = "getComponentType".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetComponentTypeSignature = GetClassSignature;
-    public static final char[] GetConstructor = "getConstructor".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$
-    public static final char[] GETDECLAREDCONSTRUCTOR_NAME = "getDeclaredConstructor".toCharArray(); //$NON-NLS-1$
-    public static final char[] GETDECLAREDCONSTRUCTOR_SIGNATURE = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$
-    // predefined methods constant names
-    public static final char[] GETDECLAREDFIELD_NAME = "getDeclaredField".toCharArray(); //$NON-NLS-1$
-    public static final char[] GETDECLAREDFIELD_SIGNATURE = "(Ljava/lang/String;)Ljava/lang/reflect/Field;".toCharArray(); //$NON-NLS-1$
-    public static final char[] GETDECLAREDMETHOD_NAME = "getDeclaredMethod".toCharArray(); //$NON-NLS-1$
-    public static final char[] GETDECLAREDMETHOD_SIGNATURE = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetMessage = "getMessage".toCharArray(); //$NON-NLS-1$
-    public static final char[] GetMessageSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-    public static final char[] HasNext = "hasNext".toCharArray();//$NON-NLS-1$
-    public static final char[] HasNextSignature = "()Z".toCharArray();//$NON-NLS-1$
-    public static final char[] Init = "<init>".toCharArray(); //$NON-NLS-1$
-    public static final char[] IntConstrSignature = "(I)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] ITERATOR_NAME = "iterator".toCharArray(); //$NON-NLS-1$
-    public static final char[] ITERATOR_SIGNATURE = "()Ljava/util/Iterator;".toCharArray(); //$NON-NLS-1$
-    public static final char[] Intern = "intern".toCharArray(); //$NON-NLS-1$
-    public static final char[] InternSignature = GetMessageSignature;
-    public static final char[] IntIntegerSignature = "(I)Ljava/lang/Integer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] INTVALUE_INTEGER_METHOD_NAME = "intValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] INTVALUE_INTEGER_METHOD_SIGNATURE = "()I".toCharArray(); //$NON-NLS-1$
-    public static final char[] INVOKE_METHOD_METHOD_NAME = "invoke".toCharArray(); //$NON-NLS-1$
-    public static final char[] INVOKE_METHOD_METHOD_SIGNATURE = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[][] JAVA_LANG_REFLECT_ACCESSIBLEOBJECT = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "AccessibleObject".toCharArray()}; //$NON-NLS-1$
-    public static final char[][] JAVA_LANG_REFLECT_ARRAY = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "Array".toCharArray()}; //$NON-NLS-1$
-    // predefined type constant names
-    public static final char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangAssertionErrorConstantPoolName = "java/lang/AssertionError".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangByteConstantPoolName = "java/lang/Byte".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangCharacterConstantPoolName = "java/lang/Character".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangClassConstantPoolName = "java/lang/Class".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangClassSignature = "Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$
-    public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$
-    public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangReflectConstructorConstantPoolName = "java/lang/reflect/Constructor".toCharArray();   //$NON-NLS-1$
-    public static final char[] JavaLangReflectConstructorNewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] JAVALANGREFLECTFIELD_CONSTANTPOOLNAME = "java/lang/reflect/Field".toCharArray(); //$NON-NLS-1$
-    public static final char[] JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME = "java/lang/reflect/Method".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangShortConstantPoolName = "java/lang/Short".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangStringBuilderConstantPoolName = "java/lang/StringBuilder".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangStringConstantPoolName = "java/lang/String".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangStringSignature = "Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangSystemConstantPoolName = "java/lang/System".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaLangVoidConstantPoolName = "java/lang/Void".toCharArray(); //$NON-NLS-1$
-    public static final char[] JavaUtilIteratorConstantPoolName = "java/util/Iterator".toCharArray(); //$NON-NLS-1$
-    public static final char[] LongConstrSignature = "(J)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] longLongSignature = "(J)Ljava/lang/Long;".toCharArray(); //$NON-NLS-1$
-    public static final char[] LONGVALUE_LONG_METHOD_NAME = "longValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] LONGVALUE_LONG_METHOD_SIGNATURE = "()J".toCharArray(); //$NON-NLS-1$
-    public static final char[] NewInstance = "newInstance".toCharArray(); //$NON-NLS-1$
-    public static final char[] NewInstanceSignature = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] Next = "next".toCharArray();//$NON-NLS-1$
-    public static final char[] NextSignature = "()Ljava/lang/Object;".toCharArray();//$NON-NLS-1$
-    public static final char[] ObjectConstrSignature = "(Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] ObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
-    public static final char[] Ordinal = "ordinal".toCharArray(); //$NON-NLS-1$
-    public static final char[] OrdinalSignature = "()I".toCharArray(); //$NON-NLS-1$
-    public static final char[] Out = "out".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_BOOLEAN_METHOD_NAME = "setBoolean".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;Z)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_BYTE_METHOD_NAME = "setByte".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;B)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_CHAR_METHOD_NAME = "setChar".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;C)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_DOUBLE_METHOD_NAME = "setDouble".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;D)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_FLOAT_METHOD_NAME = "setFloat".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;F)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_INT_METHOD_NAME = "setInt".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;I)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_LONG_METHOD_NAME = "setLong".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;J)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_OBJECT_METHOD_NAME = "set".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_SHORT_METHOD_NAME = "setShort".toCharArray(); //$NON-NLS-1$
-    public static final char[] SET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;S)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] SETACCESSIBLE_NAME = "setAccessible".toCharArray(); //$NON-NLS-1$
-    public static final char[] SETACCESSIBLE_SIGNATURE = "(Z)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] ShortConstrSignature = "(S)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] shortShortSignature = "(S)Ljava/lang/Short;".toCharArray(); //$NON-NLS-1$
-    public static final char[] SHORTVALUE_SHORT_METHOD_NAME = "shortValue".toCharArray(); //$NON-NLS-1$
-    public static final char[] SHORTVALUE_SHORT_METHOD_SIGNATURE = "()S".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendCharSignature = "(C)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendDoubleSignature = "(D)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendFloatSignature = "(F)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendIntSignature = "(I)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendLongSignature = "(J)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBufferAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendBooleanSignature = "(Z)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendCharSignature = "(C)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendDoubleSignature = "(D)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendFloatSignature = "(F)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendIntSignature = "(I)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendLongSignature = "(J)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringBuilderAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
-    public static final char[] StringConstructorSignature = "(Ljava/lang/String;)V".toCharArray(); //$NON-NLS-1$
-    public static final char[] This = "this".toCharArray(); //$NON-NLS-1$
-    public static final char[] ToString = "toString".toCharArray(); //$NON-NLS-1$
-    public static final char[] ToStringSignature = GetMessageSignature;
-    public static final char[] TYPE = "TYPE".toCharArray(); //$NON-NLS-1$
-    public static final char[] ValueOf = "valueOf".toCharArray(); //$NON-NLS-1$
-    public static final char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-    public static final char[] ValueOfCharSignature = "(C)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-    public static final char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-    public static final char[] ValueOfFloatSignature = "(F)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
-    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[] ValueOfStringClassSignature = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;".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/annotation/Inherited;".toCharArray(); //$NON-NLS-1$
-/**
- * ConstantPool constructor comment.
- */
-public ConstantPool(ClassFile classFile) {
-    this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE);
-    this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE);
-    this.methodsAndFieldsCache = new HashtableOfObject(METHODS_AND_FIELDS_INITIAL_SIZE);
-    this.classCache = new CharArrayCache(CLASS_INITIAL_SIZE);
-    this.nameAndTypeCacheForFieldsAndMethods = new HashtableOfObject(NAMEANDTYPE_INITIAL_SIZE);
-    this.offsets = new int[5];
-    initialize(classFile);
-}
-public void initialize(ClassFile givenClassFile) {
-    this.poolContent = givenClassFile.header;
-    this.currentOffset = givenClassFile.headerOffset;
-    // currentOffset is initialized to 0 by default
-    this.currentIndex = 1;
-    this.classFile = givenClassFile;
-}
-/**
- * Return the content of the receiver
- */
-public byte[] dumpBytes() {
-    System.arraycopy(this.poolContent, 0, (this.poolContent = new byte[this.currentOffset]), 0, this.currentOffset);
-    return this.poolContent;
-}
-public int literalIndex(byte[] utf8encoding, char[] stringCharArray) {
-    int index;
-    if ((index = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
-        // The entry doesn't exit yet
-        if ((index = -index)> 0xFFFF) {
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        this.currentIndex++;
-        // Write the tag first
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(Utf8Tag);
-        int utf8encodingLength = utf8encoding.length;
-        if (this.currentOffset + 2 + utf8encodingLength >= this.poolContent.length) {
-            // we need to resize the poolContent array because we won't have
-            // enough space to write the length
-            resizePoolContents(2 + utf8encodingLength);
-        }
-        this.poolContent[this.currentOffset++] = (byte) (utf8encodingLength >> 8);
-        this.poolContent[this.currentOffset++] = (byte) utf8encodingLength;
-        // add in once the whole byte array
-        System.arraycopy(utf8encoding, 0, this.poolContent, this.currentOffset, utf8encodingLength);
-        this.currentOffset += utf8encodingLength;
-    }
-    return index;
-}
-public int literalIndex(TypeBinding binding) {
-	TypeBinding typeBinding = binding.leafComponentType();
-	if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
-		Util.recordNestedType(this.classFile, typeBinding);
+	public ClassFile classFile;
+	public static final char[] Append = "append".toCharArray(); //$NON-NLS-1$
+	public static final char[] ARRAY_NEWINSTANCE_NAME = "newInstance".toCharArray(); //$NON-NLS-1$
+	public static final char[] ARRAY_NEWINSTANCE_SIGNATURE = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayCopy = "arraycopy".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayCopySignature = "(Ljava/lang/Object;ILjava/lang/Object;II)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayJavaLangClassConstantPoolName = "[Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ArrayJavaLangObjectConstantPoolName = "[Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] booleanBooleanSignature = "(Z)Ljava/lang/Boolean;".toCharArray(); //$NON-NLS-1$
+	public static final char[] BooleanConstrSignature = "(Z)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_NAME = "booleanValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE = "()Z".toCharArray(); //$NON-NLS-1$
+	public static final char[] byteByteSignature = "(B)Ljava/lang/Byte;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ByteConstrSignature = "(B)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] BYTEVALUE_BYTE_METHOD_NAME = "byteValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] BYTEVALUE_BYTE_METHOD_SIGNATURE = "()B".toCharArray(); //$NON-NLS-1$
+	public static final char[] charCharacterSignature = "(C)Ljava/lang/Character;".toCharArray(); //$NON-NLS-1$
+	public static final char[] CharConstrSignature = "(C)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] CHARVALUE_CHARACTER_METHOD_NAME = "charValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] CHARVALUE_CHARACTER_METHOD_SIGNATURE = "()C".toCharArray(); //$NON-NLS-1$
+	public static final char[] Clinit = "<clinit>".toCharArray(); //$NON-NLS-1$
+	public static final char[] DefaultConstructorSignature = "()V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ClinitSignature = DefaultConstructorSignature;
+	public static final char[] Close = "close".toCharArray(); //$NON-NLS-1$
+	public static final char[] CloseSignature = "()V".toCharArray(); //$NON-NLS-1$
+	public static final char[] DesiredAssertionStatus = "desiredAssertionStatus".toCharArray(); //$NON-NLS-1$
+	public static final char[] DesiredAssertionStatusSignature = "()Z".toCharArray(); //$NON-NLS-1$
+	public static final char[] DoubleConstrSignature = "(D)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] doubleDoubleSignature = "(D)Ljava/lang/Double;".toCharArray(); //$NON-NLS-1$
+	public static final char[] DOUBLEVALUE_DOUBLE_METHOD_NAME = "doubleValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE = "()D".toCharArray(); //$NON-NLS-1$
+	public static final char[] Exit = "exit".toCharArray(); //$NON-NLS-1$
+	public static final char[] ExitIntSignature = "(I)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] FloatConstrSignature = "(F)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] floatFloatSignature = "(F)Ljava/lang/Float;".toCharArray(); //$NON-NLS-1$
+	public static final char[] FLOATVALUE_FLOAT_METHOD_NAME = "floatValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] FLOATVALUE_FLOAT_METHOD_SIGNATURE = "()F".toCharArray(); //$NON-NLS-1$
+	public static final char[] ForName = "forName".toCharArray(); //$NON-NLS-1$
+	public static final char[] ForNameSignature = "(Ljava/lang/String;)Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BOOLEAN_METHOD_NAME = "getBoolean".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BYTE_METHOD_NAME = "getByte".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;)B".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_CHAR_METHOD_NAME = "getChar".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;)C".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_DOUBLE_METHOD_NAME = "getDouble".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;)D".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_FLOAT_METHOD_NAME = "getFloat".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;)F".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_INT_METHOD_NAME = "getInt".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;)I".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_LONG_METHOD_NAME = "getLong".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;)J".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_OBJECT_METHOD_NAME = "get".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_SHORT_METHOD_NAME = "getShort".toCharArray(); //$NON-NLS-1$
+	public static final char[] GET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;)S".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetClass = "getClass".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetClassSignature = "()Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetComponentType = "getComponentType".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetComponentTypeSignature = GetClassSignature;
+	public static final char[] GetConstructor = "getConstructor".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetConstructorSignature = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDCONSTRUCTOR_NAME = "getDeclaredConstructor".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDCONSTRUCTOR_SIGNATURE = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;".toCharArray(); //$NON-NLS-1$
+	// predefined methods constant names
+	public static final char[] GETDECLAREDFIELD_NAME = "getDeclaredField".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDFIELD_SIGNATURE = "(Ljava/lang/String;)Ljava/lang/reflect/Field;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDMETHOD_NAME = "getDeclaredMethod".toCharArray(); //$NON-NLS-1$
+	public static final char[] GETDECLAREDMETHOD_SIGNATURE = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetMessage = "getMessage".toCharArray(); //$NON-NLS-1$
+	public static final char[] GetMessageSignature = "()Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] HasNext = "hasNext".toCharArray();//$NON-NLS-1$
+	public static final char[] HasNextSignature = "()Z".toCharArray();//$NON-NLS-1$
+	public static final char[] Init = "<init>".toCharArray(); //$NON-NLS-1$
+	public static final char[] IntConstrSignature = "(I)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ITERATOR_NAME = "iterator".toCharArray(); //$NON-NLS-1$
+	public static final char[] ITERATOR_SIGNATURE = "()Ljava/util/Iterator;".toCharArray(); //$NON-NLS-1$
+	public static final char[] Intern = "intern".toCharArray(); //$NON-NLS-1$
+	public static final char[] InternSignature = GetMessageSignature;
+	public static final char[] IntIntegerSignature = "(I)Ljava/lang/Integer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] INTVALUE_INTEGER_METHOD_NAME = "intValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] INTVALUE_INTEGER_METHOD_SIGNATURE = "()I".toCharArray(); //$NON-NLS-1$
+	public static final char[] INVOKE_METHOD_METHOD_NAME = "invoke".toCharArray(); //$NON-NLS-1$
+	public static final char[] INVOKE_METHOD_METHOD_SIGNATURE = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[][] JAVA_LANG_REFLECT_ACCESSIBLEOBJECT = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "AccessibleObject".toCharArray()}; //$NON-NLS-1$
+	public static final char[][] JAVA_LANG_REFLECT_ARRAY = new char[][] {TypeConstants.JAVA, TypeConstants.LANG, TypeConstants.REFLECT, "Array".toCharArray()}; //$NON-NLS-1$
+	// predefined type constant names
+	public static final char[] JavaIoPrintStreamSignature = "Ljava/io/PrintStream;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangAssertionErrorConstantPoolName = "java/lang/AssertionError".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangBooleanConstantPoolName = "java/lang/Boolean".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangByteConstantPoolName = "java/lang/Byte".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangCharacterConstantPoolName = "java/lang/Character".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangClassConstantPoolName = "java/lang/Class".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangClassNotFoundExceptionConstantPoolName = "java/lang/ClassNotFoundException".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangClassSignature = "Ljava/lang/Class;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangLongConstantPoolName = "java/lang/Long".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangNoClassDefFoundErrorConstantPoolName = "java/lang/NoClassDefFoundError".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangNoSuchFieldErrorConstantPoolName = "java/lang/NoSuchFieldError".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangObjectConstantPoolName = "java/lang/Object".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTACCESSIBLEOBJECT_CONSTANTPOOLNAME = "java/lang/reflect/AccessibleObject".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTARRAY_CONSTANTPOOLNAME = "java/lang/reflect/Array".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangReflectConstructorConstantPoolName = "java/lang/reflect/Constructor".toCharArray();   //$NON-NLS-1$
+	public static final char[] JavaLangReflectConstructorNewInstanceSignature = "([Ljava/lang/Object;)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTFIELD_CONSTANTPOOLNAME = "java/lang/reflect/Field".toCharArray(); //$NON-NLS-1$
+	public static final char[] JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME = "java/lang/reflect/Method".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangShortConstantPoolName = "java/lang/Short".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringBufferConstantPoolName = "java/lang/StringBuffer".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringBuilderConstantPoolName = "java/lang/StringBuilder".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringConstantPoolName = "java/lang/String".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangStringSignature = "Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangSystemConstantPoolName = "java/lang/System".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangThrowableConstantPoolName = "java/lang/Throwable".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangVoidConstantPoolName = "java/lang/Void".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaUtilIteratorConstantPoolName = "java/util/Iterator".toCharArray(); //$NON-NLS-1$
+	public static final char[] LongConstrSignature = "(J)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] longLongSignature = "(J)Ljava/lang/Long;".toCharArray(); //$NON-NLS-1$
+	public static final char[] LONGVALUE_LONG_METHOD_NAME = "longValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] LONGVALUE_LONG_METHOD_SIGNATURE = "()J".toCharArray(); //$NON-NLS-1$
+	public static final char[] NewInstance = "newInstance".toCharArray(); //$NON-NLS-1$
+	public static final char[] NewInstanceSignature = "(Ljava/lang/Class;[I)Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] Next = "next".toCharArray();//$NON-NLS-1$
+	public static final char[] NextSignature = "()Ljava/lang/Object;".toCharArray();//$NON-NLS-1$
+	public static final char[] ObjectConstrSignature = "(Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ObjectSignature = "Ljava/lang/Object;".toCharArray(); //$NON-NLS-1$
+	public static final char[] Ordinal = "ordinal".toCharArray(); //$NON-NLS-1$
+	public static final char[] OrdinalSignature = "()I".toCharArray(); //$NON-NLS-1$
+	public static final char[] Out = "out".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BOOLEAN_METHOD_NAME = "setBoolean".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BOOLEAN_METHOD_SIGNATURE = "(Ljava/lang/Object;Z)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BYTE_METHOD_NAME = "setByte".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_BYTE_METHOD_SIGNATURE = "(Ljava/lang/Object;B)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_CHAR_METHOD_NAME = "setChar".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_CHAR_METHOD_SIGNATURE = "(Ljava/lang/Object;C)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_DOUBLE_METHOD_NAME = "setDouble".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_DOUBLE_METHOD_SIGNATURE = "(Ljava/lang/Object;D)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_FLOAT_METHOD_NAME = "setFloat".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_FLOAT_METHOD_SIGNATURE = "(Ljava/lang/Object;F)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_INT_METHOD_NAME = "setInt".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_INT_METHOD_SIGNATURE = "(Ljava/lang/Object;I)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_LONG_METHOD_NAME = "setLong".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_LONG_METHOD_SIGNATURE = "(Ljava/lang/Object;J)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_OBJECT_METHOD_NAME = "set".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_OBJECT_METHOD_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Object;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_SHORT_METHOD_NAME = "setShort".toCharArray(); //$NON-NLS-1$
+	public static final char[] SET_SHORT_METHOD_SIGNATURE = "(Ljava/lang/Object;S)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] SETACCESSIBLE_NAME = "setAccessible".toCharArray(); //$NON-NLS-1$
+	public static final char[] SETACCESSIBLE_SIGNATURE = "(Z)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] ShortConstrSignature = "(S)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] shortShortSignature = "(S)Ljava/lang/Short;".toCharArray(); //$NON-NLS-1$
+	public static final char[] SHORTVALUE_SHORT_METHOD_NAME = "shortValue".toCharArray(); //$NON-NLS-1$
+	public static final char[] SHORTVALUE_SHORT_METHOD_SIGNATURE = "()S".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendBooleanSignature = "(Z)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendCharSignature = "(C)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendDoubleSignature = "(D)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendFloatSignature = "(F)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendIntSignature = "(I)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendLongSignature = "(J)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBufferAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuffer;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendBooleanSignature = "(Z)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendCharSignature = "(C)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendDoubleSignature = "(D)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendFloatSignature = "(F)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendIntSignature = "(I)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendLongSignature = "(J)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendObjectSignature = "(Ljava/lang/Object;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringBuilderAppendStringSignature = "(Ljava/lang/String;)Ljava/lang/StringBuilder;".toCharArray(); //$NON-NLS-1$
+	public static final char[] StringConstructorSignature = "(Ljava/lang/String;)V".toCharArray(); //$NON-NLS-1$
+	public static final char[] This = "this".toCharArray(); //$NON-NLS-1$
+	public static final char[] ToString = "toString".toCharArray(); //$NON-NLS-1$
+	public static final char[] ToStringSignature = GetMessageSignature;
+	public static final char[] TYPE = "TYPE".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOf = "valueOf".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfBooleanSignature = "(Z)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfCharSignature = "(C)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfDoubleSignature = "(D)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	public static final char[] ValueOfFloatSignature = "(F)Ljava/lang/String;".toCharArray(); //$NON-NLS-1$
+	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[] ValueOfStringClassSignature = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;".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/annotation/Inherited;".toCharArray(); //$NON-NLS-1$
+	// java 7  java.lang.SafeVarargs
+	public static final char[] JAVA_LANG_SAFEVARARGS = "Ljava/lang/SafeVarargs;".toCharArray(); //$NON-NLS-1$
+	// java 7 java.lang.invoke.MethodHandle.invokeExact(..)/invokeGeneric(..)
+	public static final char[] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = "Ljava/lang/invoke/MethodHandle$PolymorphicSignature;".toCharArray(); //$NON-NLS-1$
+
+	public static final char[] HashCode = "hashCode".toCharArray(); //$NON-NLS-1$
+	public static final char[] HashCodeSignature = "()I".toCharArray(); //$NON-NLS-1$; 
+	public static final char[] Equals = "equals".toCharArray(); //$NON-NLS-1$
+	public static final char[] EqualsSignature = "(Ljava/lang/Object;)Z".toCharArray(); //$NON-NLS-1$; 
+	public static final char[] AddSuppressed = "addSuppressed".toCharArray(); //$NON-NLS-1$;
+	public static final char[] AddSuppressedSignature = "(Ljava/lang/Throwable;)V".toCharArray(); //$NON-NLS-1$
+	/**
+	 * ConstantPool constructor comment.
+	 */
+	public ConstantPool(ClassFile classFile) {
+		this.UTF8Cache = new CharArrayCache(UTF8_INITIAL_SIZE);
+		this.stringCache = new CharArrayCache(STRING_INITIAL_SIZE);
+		this.methodsAndFieldsCache = new HashtableOfObject(METHODS_AND_FIELDS_INITIAL_SIZE);
+		this.classCache = new CharArrayCache(CLASS_INITIAL_SIZE);
+		this.nameAndTypeCacheForFieldsAndMethods = new HashtableOfObject(NAMEANDTYPE_INITIAL_SIZE);
+		this.offsets = new int[5];
+		initialize(classFile);
 	}
-	return literalIndex(binding.signature());
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param utf8Constant char[]
- * @return <CODE>int</CODE>
- */
-public int literalIndex(char[] utf8Constant) {
-    int index;
-    if ((index = this.UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) {
-        if ((index = -index)> 0xFFFF) {
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        // The entry doesn't exit yet
-        // Write the tag first
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(Utf8Tag);
-        // Then the size of the stringName array
-        int savedCurrentOffset = this.currentOffset;
-        if (this.currentOffset + 2 >= this.poolContent.length) {
-            // we need to resize the poolContent array because we won't have
-            // enough space to write the length
-            resizePoolContents(2);
-        }
-        this.currentOffset += 2;
-        length = 0;
-        for (int i = 0; i < utf8Constant.length; i++) {
-            char current = utf8Constant[i];
-            if ((current >= 0x0001) && (current <= 0x007F)) {
-                // we only need one byte: ASCII table
-                writeU1(current);
-                length++;
-            } else {
-                if (current > 0x07FF) {
-                    // we need 3 bytes
-                    length += 3;
-                    writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
-                    writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
-                    writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-                } else {
-                    // we can be 0 or between 0x0080 and 0x07FF
-                    // In that case we only need 2 bytes
-                    length += 2;
-                    writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
-                    writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-                }
-            }
-        }
-        if (length >= 65535) {
-            this.currentOffset = savedCurrentOffset - 1;
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType());
-        }
-        if (index > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        this.currentIndex++;
-        // Now we know the length that we have to write in the constant pool
-        // we use savedCurrentOffset to do that
-        this.poolContent[savedCurrentOffset] = (byte) (length >> 8);
-        this.poolContent[savedCurrentOffset + 1] = (byte) length;
-    }
-    return index;
-}
-public int literalIndex(char[] stringCharArray, byte[] utf8encoding) {
-    int index;
-    if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
-        // The entry doesn't exit yet
-        this.currentIndex++;
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        // Write the tag first
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(StringTag);
-        // Then the string index
-        int stringIndexOffset = this.currentOffset;
-        if (this.currentOffset + 2 >= this.poolContent.length) {
-            resizePoolContents(2);
-        }
-        this.currentOffset+=2;
-
-        final int stringIndex = literalIndex(utf8encoding, stringCharArray);
-        this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
-        this.poolContent[stringIndexOffset] = (byte) stringIndex;
-    }
-    return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the double
- * value. If the double is not already present into the pool, it is added. The
- * double cache is updated and it returns the right index.
- *
- * @param key <CODE>double</CODE>
- * @return <CODE>int</CODE>
- */
-public int literalIndex(double key) {
-    //Retrieve the index from the cache
-    // The double constant takes two indexes into the constant pool, but we only store
-    // the first index into the long table
-    int index;
-    // lazy initialization for base type caches
-    // If it is null, initialize it, otherwise use it
-    if (this.doubleCache == null) {
-            this.doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE);
-    }
-    if ((index = this.doubleCache.putIfAbsent(key, this.currentIndex)) < 0) {
-        if ((index = -index)> 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        this.currentIndex += 2; // a double needs an extra place into the constant pool
-        // Write the double into the constant pool
-        // First add the tag
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(DoubleTag);
-        // Then add the 8 bytes representing the double
-        long temp = java.lang.Double.doubleToLongBits(key);
-        length = this.poolContent.length;
-        if (this.currentOffset + 8 >= length) {
-            resizePoolContents(8);
-        }
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 56);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 48);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 40);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 32);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 24);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 16);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 8);
-        this.poolContent[this.currentOffset++] = (byte) temp;
-    }
-    return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the float
- * value. If the float is not already present into the pool, it is added. The
- * int cache is updated and it returns the right index.
- *
- * @param key <CODE>float</CODE>
- * @return <CODE>int</CODE>
- */
-public int literalIndex(float key) {
-    //Retrieve the index from the cache
-    int index;
-    // lazy initialization for base type caches
-    // If it is null, initialize it, otherwise use it
-    if (this.floatCache == null) {
-        this.floatCache = new FloatCache(FLOAT_INITIAL_SIZE);
-    }
-    if ((index = this.floatCache.putIfAbsent(key, this.currentIndex)) < 0) {
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        this.currentIndex++;
-        // Write the float constant entry into the constant pool
-        // First add the tag
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(FloatTag);
-        // Then add the 4 bytes representing the float
-        int temp = java.lang.Float.floatToIntBits(key);
-        if (this.currentOffset + 4 >= this.poolContent.length) {
-            resizePoolContents(4);
-        }
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 24);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 16);
-        this.poolContent[this.currentOffset++] = (byte) (temp >>> 8);
-        this.poolContent[this.currentOffset++] = (byte) temp;
-    }
-    return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the int
- * value. If the int is not already present into the pool, it is added. The
- * int cache is updated and it returns the right index.
- *
- * @param key <CODE>int</CODE>
- * @return <CODE>int</CODE>
- */
-public int literalIndex(int key) {
-    //Retrieve the index from the cache
-    int index;
-    // lazy initialization for base type caches
-    // If it is null, initialize it, otherwise use it
-    if (this.intCache == null) {
-        this.intCache = new IntegerCache(INT_INITIAL_SIZE);
-    }
-    if ((index = this.intCache.putIfAbsent(key, this.currentIndex)) < 0) {
-        this.currentIndex++;
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
- 	   // Write the integer constant entry into the constant pool
-        // First add the tag
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(IntegerTag);
-        // Then add the 4 bytes representing the int
-        if (this.currentOffset + 4 >= this.poolContent.length) {
-            resizePoolContents(4);
-        }
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 24);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 16);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 8);
-        this.poolContent[this.currentOffset++] = (byte) key;
-    }
-    return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the long
- * value. If the long is not already present into the pool, it is added. The
- * long cache is updated and it returns the right index.
- *
- * @param key <CODE>long</CODE>
- * @return <CODE>int</CODE>
- */
-public int literalIndex(long key) {
-    // Retrieve the index from the cache
-    // The long constant takes two indexes into the constant pool, but we only store
-    // the first index into the long table
-    int index;
-    // lazy initialization for base type caches
-    // If it is null, initialize it, otherwise use it
-    if (this.longCache == null) {
-        this.longCache = new LongCache(LONG_INITIAL_SIZE);
-    }
-    if ((index = this.longCache.putIfAbsent(key, this.currentIndex)) < 0) {
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        this.currentIndex+= 2; // long value need an extra place into thwe constant pool
-        // Write the long into the constant pool
-        // First add the tag
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(LongTag);
-        // Then add the 8 bytes representing the long
-        if (this.currentOffset + 8 >= this.poolContent.length) {
-            resizePoolContents(8);
-        }
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 56);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 48);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 40);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 32);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 24);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 16);
-        this.poolContent[this.currentOffset++] = (byte) (key >>> 8);
-        this.poolContent[this.currentOffset++] = (byte) key;
-    }
-    return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param stringConstant java.lang.String
- * @return <CODE>int</CODE>
- */
-public int literalIndex(String stringConstant) {
-    int index;
-    char[] stringCharArray = stringConstant.toCharArray();
-    if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
-        // The entry doesn't exit yet
-        this.currentIndex++;
-        if ((index  = -index)> 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        // Write the tag first
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(StringTag);
-        // Then the string index
-        int stringIndexOffset = this.currentOffset;
-        if (this.currentOffset + 2 >= this.poolContent.length) {
-            resizePoolContents(2);
-        }
-        this.currentOffset+=2;
-        final int stringIndex = literalIndex(stringCharArray);
-        this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
-        this.poolContent[stringIndexOffset] = (byte) stringIndex;
-    }
-    return index;
-}
-public int literalIndexForType(final char[] constantPoolName) {
-    int index;
-    if ((index = this.classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) {
-        // The entry doesn't exit yet
-        this.currentIndex++;
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-       this.offsets[index] = this.currentOffset;
-        writeU1(ClassTag);
-
-        // Then the name index
-        int nameIndexOffset = this.currentOffset;
-        if (this.currentOffset + 2 >= this.poolContent.length) {
-            resizePoolContents(2);
-        }
-        this.currentOffset+=2;
-        final int nameIndex = literalIndex(constantPoolName);
-        this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8);
-        this.poolContent[nameIndexOffset] = (byte) nameIndex;
-    }
-    return index;
-}
-/*
- * This method returns the index into the constantPool corresponding to the type descriptor
- * corresponding to a type constant pool name
- * binding must not be an array type.
- */
-public int literalIndexForType(final TypeBinding binding) {
-	TypeBinding typeBinding = binding.leafComponentType();
-	if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
-		Util.recordNestedType(this.classFile, typeBinding);
+	public void initialize(ClassFile givenClassFile) {
+		this.poolContent = givenClassFile.header;
+		this.currentOffset = givenClassFile.headerOffset;
+		// currentOffset is initialized to 0 by default
+		this.currentIndex = 1;
+		this.classFile = givenClassFile;
 	}
-	return this.literalIndexForType(binding.constantPoolName());
-}
-public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) {
-    int index;
-    if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) {
-        // it doesn't exist yet
-        this.currentIndex++;
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        // Write the interface method ref constant into the constant pool
-        // First add the tag
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag);
-
-        int classIndexOffset = this.currentOffset;
-        if (this.currentOffset + 4 >= this.poolContent.length) {
-            resizePoolContents(4);
-        }
-        this.currentOffset+=4;
-
-        final int classIndex = literalIndexForType(declaringClass);
-        final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature);
-
-        this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8);
-        this.poolContent[classIndexOffset++] = (byte) classIndex;
-        this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8);
-        this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex;
-    }
-    return index;
-}
-public int literalIndexForMethod(TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) {
-	if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
-		Util.recordNestedType(this.classFile, declaringClass);
+	/**
+	 * Return the content of the receiver
+	 */
+	public byte[] dumpBytes() {
+		System.arraycopy(this.poolContent, 0, (this.poolContent = new byte[this.currentOffset]), 0, this.currentOffset);
+		return this.poolContent;
 	}
-	return this.literalIndexForMethod(declaringClass.constantPoolName(), selector, signature, isInterface);
-}
-public int literalIndexForNameAndType(char[] name, char[] signature) {
-    int index;
-    if ((index = putInNameAndTypeCacheIfAbsent(name, signature, this.currentIndex)) < 0) {
-        // The entry doesn't exit yet
-        this.currentIndex++;
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(NameAndTypeTag);
-        int nameIndexOffset = this.currentOffset;
-        if (this.currentOffset + 4 >= this.poolContent.length) {
-            resizePoolContents(4);
-        }
-        this.currentOffset+=4;
-
-        final int nameIndex = literalIndex(name);
-        final int typeIndex = literalIndex(signature);
-        this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8);
-        this.poolContent[nameIndexOffset++] = (byte) nameIndex;
-        this.poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8);
-        this.poolContent[nameIndexOffset] = (byte) typeIndex;
-    }
-    return index;
-}
-public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) {
-    int index;
-    if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) {
-        this.currentIndex++;
-        // doesn't exist yet
-        if ((index = -index) > 0xFFFF){
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        // Write the interface method ref constant into the constant pool
-        // First add the tag
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(FieldRefTag);
-        int classIndexOffset = this.currentOffset;
-        if (this.currentOffset + 4 >= this.poolContent.length) {
-            resizePoolContents(4);
-        }
-        this.currentOffset+=4;
-
-        final int classIndex = literalIndexForType(declaringClass);
-        final int nameAndTypeIndex = literalIndexForNameAndType(name, signature);
-
-        this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8);
-        this.poolContent[classIndexOffset++] = (byte) classIndex;
-        this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8);
-        this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex;
-    }
-    return index;
-}
-/**
- * This method returns the index into the constantPool corresponding to the type descriptor.
- *
- * @param stringCharArray char[]
- * @return <CODE>int</CODE>
- */
-public int literalIndexForLdc(char[] stringCharArray) {
-    int savedCurrentIndex = this.currentIndex;
-    int savedCurrentOffset = this.currentOffset;
-    int index;
-    if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
-        if ((index = -index)> 0xFFFF) {
-            this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-        }
-        // The entry doesn't exit yet
-        this.currentIndex++;
-        // Write the tag first
-        int length = this.offsets.length;
-        if (length <= index) {
-        	// resize
-            System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
-        }
-        this.offsets[index] = this.currentOffset;
-        writeU1(StringTag);
-
-        // Then the string index
-        int stringIndexOffset = this.currentOffset;
-        if (this.currentOffset + 2 >= this.poolContent.length) {
-            resizePoolContents(2);
-        }
-        this.currentOffset+=2;
-
-        int stringIndex;
-        if ((stringIndex = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
-            if ((stringIndex = -stringIndex)> 0xFFFF) {
-                this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
-            }
-            // The entry doesn't exit yet
-            this.currentIndex++;
-            // Write the tag first
-            length = this.offsets.length;
-            if (length <= stringIndex) {
-            	// resize
-                System.arraycopy(this.offsets, 0, (this.offsets = new int[stringIndex * 2]), 0, length);
-            }
-            this.offsets[stringIndex] = this.currentOffset;
-            writeU1(Utf8Tag);
-            // Then the size of the stringName array
-            int lengthOffset = this.currentOffset;
-            if (this.currentOffset + 2 >= this.poolContent.length) {
-                // we need to resize the poolContent array because we won't have
-                // enough space to write the length
-                resizePoolContents(2);
-            }
-            this.currentOffset += 2;
-            length = 0;
-            for (int i = 0; i < stringCharArray.length; i++) {
-                char current = stringCharArray[i];
-                if ((current >= 0x0001) && (current <= 0x007F)) {
-                    // we only need one byte: ASCII table
-                    length++;
-                    if (this.currentOffset + 1 >= this.poolContent.length) {
-                        // we need to resize the poolContent array because we won't have
-                        // enough space to write the length
-                        resizePoolContents(1);
-                    }
-                    this.poolContent[this.currentOffset++] = (byte)(current);
-                } else
-                    if (current > 0x07FF) {
-                        // we need 3 bytes
-                        length += 3;
-                        if (this.currentOffset + 3 >= this.poolContent.length) {
-                            // we need to resize the poolContent array because we won't have
-                            // enough space to write the length
-                            resizePoolContents(3);
-                        }
-                        this.poolContent[this.currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
-                        this.poolContent[this.currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
-                        this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-                    } else {
-                        if (this.currentOffset + 2 >= this.poolContent.length) {
-                            // we need to resize the poolContent array because we won't have
-                            // enough space to write the length
-                            resizePoolContents(2);
-                        }
-                        // we can be 0 or between 0x0080 and 0x07FF
-                        // In that case we only need 2 bytes
-                        length += 2;
-                        this.poolContent[this.currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
-                        this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
-                    }
-            }
-            if (length >= 65535) {
-                this.currentOffset = savedCurrentOffset;
-                this.currentIndex = savedCurrentIndex;
-                this.stringCache.remove(stringCharArray);
-                this.UTF8Cache.remove(stringCharArray);
-                return 0;
-            }
-            this.poolContent[lengthOffset++] = (byte) (length >> 8);
-            this.poolContent[lengthOffset] = (byte) length;
-        }
-        this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
-        this.poolContent[stringIndexOffset] = (byte) stringIndex;
-    }
-    return index;
-}
-/**
- * @param key1 the given name
- * @param key2 the given signature
- * @param value the given index
- * @return the new index
- */
-private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) {
-    int index ;
-    Object key1Value = this.nameAndTypeCacheForFieldsAndMethods.get(key1);
-    if (key1Value == null) {
-        CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key2, value);
-        index = -value;
-        this.nameAndTypeCacheForFieldsAndMethods.put(key1, cachedIndexEntry);
-    } else if (key1Value instanceof CachedIndexEntry) {
-        // adding a second entry
-        CachedIndexEntry entry = (CachedIndexEntry) key1Value;
-        if (CharOperation.equals(key2, entry.signature)) {
-            index = entry.index;
-        } else {
-            CharArrayCache charArrayCache = new CharArrayCache();
-            charArrayCache.putIfAbsent(entry.signature, entry.index);
-            index = charArrayCache.putIfAbsent(key2, value);
-            this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache);
-        }
-    } else {
-        CharArrayCache charArrayCache = (CharArrayCache) key1Value;
-        index = charArrayCache.putIfAbsent(key2, value);
-    }
-    return index;
-}
-/**
- * @param key1 the given declaring class name
- * @param key2 the given field name or method selector
- * @param key3 the given signature
- * @param value the new index
- * @return the given index
- */
-private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) {
-    int index;
-    HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1);
-    if (key1Value == null) {
-        key1Value = new HashtableOfObject();
-        this.methodsAndFieldsCache.put(key1, key1Value);
-        CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value);
-        index = -value;
-        key1Value.put(key2, cachedIndexEntry);
-    } else {
-        Object key2Value = key1Value.get(key2);
-        if (key2Value == null) {
-            CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value);
-            index = -value;
-            key1Value.put(key2, cachedIndexEntry);
-        } else if (key2Value instanceof CachedIndexEntry) {
-            // adding a second entry
-            CachedIndexEntry entry = (CachedIndexEntry) key2Value;
-            if (CharOperation.equals(key3, entry.signature)) {
-                index = entry.index;
-            } else {
-                CharArrayCache charArrayCache = new CharArrayCache();
-                charArrayCache.putIfAbsent(entry.signature, entry.index);
-                index = charArrayCache.putIfAbsent(key3, value);
-                key1Value.put(key2, charArrayCache);
-            }
-        } else {
-            CharArrayCache charArrayCache = (CharArrayCache) key2Value;
-            index = charArrayCache.putIfAbsent(key3, value);
-        }
-    }
-    return index;
-}
-/**
- * This method is used to clean the receiver in case of a clinit header is generated, but the
- * clinit has no code.
- * This implementation assumes that the clinit is the first method to be generated.
- * @see org.eclipse.jdt.internal.compiler.ast.TypeDeclaration#addClinit()
- */
-public void resetForClinit(int constantPoolIndex, int constantPoolOffset) {
-    this.currentIndex = constantPoolIndex;
-    this.currentOffset = constantPoolOffset;
-    if (this.UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) {
-        this.UTF8Cache.remove(AttributeNamesConstants.CodeName);
-    }
-    if (this.UTF8Cache.get(ConstantPool.ClinitSignature) >= constantPoolIndex) {
-        this.UTF8Cache.remove(ConstantPool.ClinitSignature);
-    }
-    if (this.UTF8Cache.get(ConstantPool.Clinit) >= constantPoolIndex) {
-        this.UTF8Cache.remove(ConstantPool.Clinit);
-    }
-}
-
-/**
- * Resize the pool contents
- */
-private final void resizePoolContents(int minimalSize) {
-    int length = this.poolContent.length;
-    int toAdd = length;
-    if (toAdd < minimalSize)
-        toAdd = minimalSize;
-    System.arraycopy(this.poolContent, 0, this.poolContent = new byte[length + toAdd], 0, length);
-}
-/**
- * Write a unsigned byte into the byte array
- *
- * @param value <CODE>int</CODE> The value to write into the byte array
- */
-protected final void writeU1(int value) {
-    if (this.currentOffset + 1 >= this.poolContent.length) {
-        resizePoolContents(1);
-    }
-    this.poolContent[this.currentOffset++] = (byte) value;
-}
-/**
- * Write a unsigned byte into the byte array
- *
- * @param value <CODE>int</CODE> The value to write into the byte array
- */
-protected final void writeU2(int value) {
-    if (this.currentOffset + 2 >= this.poolContent.length) {
-        resizePoolContents(2);
-    }
-    this.poolContent[this.currentOffset++] = (byte) (value >>> 8);
-    this.poolContent[this.currentOffset++] = (byte) value;
-}
-public void reset() {
-    if (this.doubleCache != null) this.doubleCache.clear();
-    if (this.floatCache != null) this.floatCache.clear();
-    if (this.intCache != null) this.intCache.clear();
-    if (this.longCache != null) this.longCache.clear();
-    this.UTF8Cache.clear();
-    this.stringCache.clear();
-    this.methodsAndFieldsCache.clear();
-    this.classCache.clear();
-    this.nameAndTypeCacheForFieldsAndMethods.clear();
-    this.currentIndex = 1;
-    this.currentOffset = 0;
-}
-public void resetForAttributeName(char[] attributeName, int constantPoolIndex, int constantPoolOffset) {
-	this.currentIndex = constantPoolIndex;
-	this.currentOffset = constantPoolOffset;
-	if (this.UTF8Cache.get(attributeName) >= constantPoolIndex) {
-		this.UTF8Cache.remove(attributeName);
+	public int literalIndex(byte[] utf8encoding, char[] stringCharArray) {
+		int index;
+		if ((index = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			if ((index = -index)> 0xFFFF) {
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex++;
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(Utf8Tag);
+			int utf8encodingLength = utf8encoding.length;
+			if (this.currentOffset + 2 + utf8encodingLength >= this.poolContent.length) {
+				// we need to resize the poolContent array because we won't have
+				// enough space to write the length
+				resizePoolContents(2 + utf8encodingLength);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (utf8encodingLength >> 8);
+			this.poolContent[this.currentOffset++] = (byte) utf8encodingLength;
+			// add in once the whole byte array
+			System.arraycopy(utf8encoding, 0, this.poolContent, this.currentOffset, utf8encodingLength);
+			this.currentOffset += utf8encodingLength;
+		}
+		return index;
 	}
-}
+	public int literalIndex(TypeBinding binding) {
+		TypeBinding typeBinding = binding.leafComponentType();
+		if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(this.classFile, typeBinding);
+		}
+		return literalIndex(binding.signature());
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the type descriptor.
+	 *
+	 * @param utf8Constant char[]
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(char[] utf8Constant) {
+		int index;
+		if ((index = this.UTF8Cache.putIfAbsent(utf8Constant, this.currentIndex)) < 0) {
+			if ((index = -index)> 0xFFFF) {
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// The entry doesn't exit yet
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(Utf8Tag);
+			// Then the size of the stringName array
+			int savedCurrentOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				// we need to resize the poolContent array because we won't have
+				// enough space to write the length
+				resizePoolContents(2);
+			}
+			this.currentOffset += 2;
+			length = 0;
+			for (int i = 0; i < utf8Constant.length; i++) {
+				char current = utf8Constant[i];
+				if ((current >= 0x0001) && (current <= 0x007F)) {
+					// we only need one byte: ASCII table
+					writeU1(current);
+					length++;
+				} else {
+					if (current > 0x07FF) {
+						// we need 3 bytes
+						length += 3;
+						writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+						writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					} else {
+						// we can be 0 or between 0x0080 and 0x07FF
+						// In that case we only need 2 bytes
+						length += 2;
+						writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+						writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+					}
+				}
+			}
+			if (length >= 65535) {
+				this.currentOffset = savedCurrentOffset - 1;
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceForConstant(this.classFile.referenceBinding.scope.referenceType());
+			}
+			if (index > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex++;
+			// Now we know the length that we have to write in the constant pool
+			// we use savedCurrentOffset to do that
+			this.poolContent[savedCurrentOffset] = (byte) (length >> 8);
+			this.poolContent[savedCurrentOffset + 1] = (byte) length;
+		}
+		return index;
+	}
+	public int literalIndex(char[] stringCharArray, byte[] utf8encoding) {
+		int index;
+		if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(StringTag);
+			// Then the string index
+			int stringIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+
+			final int stringIndex = literalIndex(utf8encoding, stringCharArray);
+			this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
+			this.poolContent[stringIndexOffset] = (byte) stringIndex;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the double
+	 * value. If the double is not already present into the pool, it is added. The
+	 * double cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>double</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(double key) {
+		//Retrieve the index from the cache
+		// The double constant takes two indexes into the constant pool, but we only store
+		// the first index into the long table
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.doubleCache == null) {
+			this.doubleCache = new DoubleCache(DOUBLE_INITIAL_SIZE);
+		}
+		if ((index = this.doubleCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			if ((index = -index)> 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex += 2; // a double needs an extra place into the constant pool
+			// Write the double into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(DoubleTag);
+			// Then add the 8 bytes representing the double
+			long temp = java.lang.Double.doubleToLongBits(key);
+			length = this.poolContent.length;
+			if (this.currentOffset + 8 >= length) {
+				resizePoolContents(8);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 56);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 48);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 40);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 32);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) temp;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the float
+	 * value. If the float is not already present into the pool, it is added. The
+	 * int cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>float</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(float key) {
+		//Retrieve the index from the cache
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.floatCache == null) {
+			this.floatCache = new FloatCache(FLOAT_INITIAL_SIZE);
+		}
+		if ((index = this.floatCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex++;
+			// Write the float constant entry into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(FloatTag);
+			// Then add the 4 bytes representing the float
+			int temp = java.lang.Float.floatToIntBits(key);
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (temp >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) temp;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the int
+	 * value. If the int is not already present into the pool, it is added. The
+	 * int cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>int</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(int key) {
+		//Retrieve the index from the cache
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.intCache == null) {
+			this.intCache = new IntegerCache(INT_INITIAL_SIZE);
+		}
+		if ((index = this.intCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the integer constant entry into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(IntegerTag);
+			// Then add the 4 bytes representing the int
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) key;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the long
+	 * value. If the long is not already present into the pool, it is added. The
+	 * long cache is updated and it returns the right index.
+	 *
+	 * @param key <CODE>long</CODE>
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(long key) {
+		// Retrieve the index from the cache
+		// The long constant takes two indexes into the constant pool, but we only store
+		// the first index into the long table
+		int index;
+		// lazy initialization for base type caches
+		// If it is null, initialize it, otherwise use it
+		if (this.longCache == null) {
+			this.longCache = new LongCache(LONG_INITIAL_SIZE);
+		}
+		if ((index = this.longCache.putIfAbsent(key, this.currentIndex)) < 0) {
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			this.currentIndex+= 2; // long value need an extra place into thwe constant pool
+			// Write the long into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(LongTag);
+			// Then add the 8 bytes representing the long
+			if (this.currentOffset + 8 >= this.poolContent.length) {
+				resizePoolContents(8);
+			}
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 56);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 48);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 40);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 32);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 24);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 16);
+			this.poolContent[this.currentOffset++] = (byte) (key >>> 8);
+			this.poolContent[this.currentOffset++] = (byte) key;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the type descriptor.
+	 *
+	 * @param stringConstant java.lang.String
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndex(String stringConstant) {
+		int index;
+		char[] stringCharArray = stringConstant.toCharArray();
+		if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index  = -index)> 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(StringTag);
+			// Then the string index
+			int stringIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+			final int stringIndex = literalIndex(stringCharArray);
+			this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
+			this.poolContent[stringIndexOffset] = (byte) stringIndex;
+		}
+		return index;
+	}
+	public int literalIndexForType(final char[] constantPoolName) {
+		int index;
+		if ((index = this.classCache.putIfAbsent(constantPoolName, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(ClassTag);
+
+			// Then the name index
+			int nameIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+			final int nameIndex = literalIndex(constantPoolName);
+			this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8);
+			this.poolContent[nameIndexOffset] = (byte) nameIndex;
+		}
+		return index;
+	}
+	/*
+	 * This method returns the index into the constantPool corresponding to the type descriptor
+	 * corresponding to a type constant pool name
+	 * binding must not be an array type.
+	 */
+	public int literalIndexForType(final TypeBinding binding) {
+		TypeBinding typeBinding = binding.leafComponentType();
+		if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(this.classFile, typeBinding);
+		}
+		return this.literalIndexForType(binding.constantPoolName());
+	}
+	public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) {
+		int index;
+		if ((index = putInCacheIfAbsent(declaringClass, selector, signature, this.currentIndex)) < 0) {
+			// it doesn't exist yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the interface method ref constant into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(isInterface ? InterfaceMethodRefTag : MethodRefTag);
+
+			int classIndexOffset = this.currentOffset;
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.currentOffset+=4;
+
+			final int classIndex = literalIndexForType(declaringClass);
+			final int nameAndTypeIndex = literalIndexForNameAndType(selector, signature);
+
+			this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8);
+			this.poolContent[classIndexOffset++] = (byte) classIndex;
+			this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8);
+			this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex;
+		}
+		return index;
+	}
+	public int literalIndexForMethod(TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) {
+		if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
+			Util.recordNestedType(this.classFile, declaringClass);
+		}
+		return this.literalIndexForMethod(declaringClass.constantPoolName(), selector, signature, isInterface);
+	}
+	public int literalIndexForNameAndType(char[] name, char[] signature) {
+		int index;
+		if ((index = putInNameAndTypeCacheIfAbsent(name, signature, this.currentIndex)) < 0) {
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(NameAndTypeTag);
+			int nameIndexOffset = this.currentOffset;
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.currentOffset+=4;
+
+			final int nameIndex = literalIndex(name);
+			final int typeIndex = literalIndex(signature);
+			this.poolContent[nameIndexOffset++] = (byte) (nameIndex >> 8);
+			this.poolContent[nameIndexOffset++] = (byte) nameIndex;
+			this.poolContent[nameIndexOffset++] = (byte) (typeIndex >> 8);
+			this.poolContent[nameIndexOffset] = (byte) typeIndex;
+		}
+		return index;
+	}
+	public int literalIndexForField(char[] declaringClass, char[] name, char[] signature) {
+		int index;
+		if ((index = putInCacheIfAbsent(declaringClass, name, signature, this.currentIndex)) < 0) {
+			this.currentIndex++;
+			// doesn't exist yet
+			if ((index = -index) > 0xFFFF){
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// Write the interface method ref constant into the constant pool
+			// First add the tag
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(FieldRefTag);
+			int classIndexOffset = this.currentOffset;
+			if (this.currentOffset + 4 >= this.poolContent.length) {
+				resizePoolContents(4);
+			}
+			this.currentOffset+=4;
+
+			final int classIndex = literalIndexForType(declaringClass);
+			final int nameAndTypeIndex = literalIndexForNameAndType(name, signature);
+
+			this.poolContent[classIndexOffset++] = (byte) (classIndex >> 8);
+			this.poolContent[classIndexOffset++] = (byte) classIndex;
+			this.poolContent[classIndexOffset++] = (byte) (nameAndTypeIndex >> 8);
+			this.poolContent[classIndexOffset] = (byte) nameAndTypeIndex;
+		}
+		return index;
+	}
+	/**
+	 * This method returns the index into the constantPool corresponding to the type descriptor.
+	 *
+	 * @param stringCharArray char[]
+	 * @return <CODE>int</CODE>
+	 */
+	public int literalIndexForLdc(char[] stringCharArray) {
+		int savedCurrentIndex = this.currentIndex;
+		int savedCurrentOffset = this.currentOffset;
+		int index;
+		if ((index = this.stringCache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+			if ((index = -index)> 0xFFFF) {
+				this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+			}
+			// The entry doesn't exit yet
+			this.currentIndex++;
+			// Write the tag first
+			int length = this.offsets.length;
+			if (length <= index) {
+				// resize
+				System.arraycopy(this.offsets, 0, (this.offsets = new int[index * 2]), 0, length);
+			}
+			this.offsets[index] = this.currentOffset;
+			writeU1(StringTag);
+
+			// Then the string index
+			int stringIndexOffset = this.currentOffset;
+			if (this.currentOffset + 2 >= this.poolContent.length) {
+				resizePoolContents(2);
+			}
+			this.currentOffset+=2;
+
+			int stringIndex;
+			if ((stringIndex = this.UTF8Cache.putIfAbsent(stringCharArray, this.currentIndex)) < 0) {
+				if ((stringIndex = -stringIndex)> 0xFFFF) {
+					this.classFile.referenceBinding.scope.problemReporter().noMoreAvailableSpaceInConstantPool(this.classFile.referenceBinding.scope.referenceType());
+				}
+				// The entry doesn't exit yet
+				this.currentIndex++;
+				// Write the tag first
+				length = this.offsets.length;
+				if (length <= stringIndex) {
+					// resize
+					System.arraycopy(this.offsets, 0, (this.offsets = new int[stringIndex * 2]), 0, length);
+				}
+				this.offsets[stringIndex] = this.currentOffset;
+				writeU1(Utf8Tag);
+				// Then the size of the stringName array
+				int lengthOffset = this.currentOffset;
+				if (this.currentOffset + 2 >= this.poolContent.length) {
+					// we need to resize the poolContent array because we won't have
+					// enough space to write the length
+					resizePoolContents(2);
+				}
+				this.currentOffset += 2;
+				length = 0;
+				for (int i = 0; i < stringCharArray.length; i++) {
+					char current = stringCharArray[i];
+					if ((current >= 0x0001) && (current <= 0x007F)) {
+						// we only need one byte: ASCII table
+						length++;
+						if (this.currentOffset + 1 >= this.poolContent.length) {
+							// we need to resize the poolContent array because we won't have
+							// enough space to write the length
+							resizePoolContents(1);
+						}
+						this.poolContent[this.currentOffset++] = (byte)(current);
+					} else
+						if (current > 0x07FF) {
+							// we need 3 bytes
+							length += 3;
+							if (this.currentOffset + 3 >= this.poolContent.length) {
+								// we need to resize the poolContent array because we won't have
+								// enough space to write the length
+								resizePoolContents(3);
+							}
+							this.poolContent[this.currentOffset++] = (byte) (0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110 0000
+							this.poolContent[this.currentOffset++] = (byte) (0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000 0000
+							this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+						} else {
+							if (this.currentOffset + 2 >= this.poolContent.length) {
+								// we need to resize the poolContent array because we won't have
+								// enough space to write the length
+								resizePoolContents(2);
+							}
+							// we can be 0 or between 0x0080 and 0x07FF
+							// In that case we only need 2 bytes
+							length += 2;
+							this.poolContent[this.currentOffset++] = (byte) (0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100 0000
+							this.poolContent[this.currentOffset++] = (byte) (0x80 | (current & 0x3F)); // 0x80 = 1000 0000
+						}
+				}
+				if (length >= 65535) {
+					this.currentOffset = savedCurrentOffset;
+					this.currentIndex = savedCurrentIndex;
+					this.stringCache.remove(stringCharArray);
+					this.UTF8Cache.remove(stringCharArray);
+					return 0;
+				}
+				this.poolContent[lengthOffset++] = (byte) (length >> 8);
+				this.poolContent[lengthOffset] = (byte) length;
+			}
+			this.poolContent[stringIndexOffset++] = (byte) (stringIndex >> 8);
+			this.poolContent[stringIndexOffset] = (byte) stringIndex;
+		}
+		return index;
+	}
+	/**
+	 * @param key1 the given name
+	 * @param key2 the given signature
+	 * @param value the given index
+	 * @return the new index
+	 */
+	private int putInNameAndTypeCacheIfAbsent(final char[] key1, final char[] key2, int value) {
+		int index ;
+		Object key1Value = this.nameAndTypeCacheForFieldsAndMethods.get(key1);
+		if (key1Value == null) {
+			CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key2, value);
+			index = -value;
+			this.nameAndTypeCacheForFieldsAndMethods.put(key1, cachedIndexEntry);
+		} else if (key1Value instanceof CachedIndexEntry) {
+			// adding a second entry
+			CachedIndexEntry entry = (CachedIndexEntry) key1Value;
+			if (CharOperation.equals(key2, entry.signature)) {
+				index = entry.index;
+			} else {
+				CharArrayCache charArrayCache = new CharArrayCache();
+				charArrayCache.putIfAbsent(entry.signature, entry.index);
+				index = charArrayCache.putIfAbsent(key2, value);
+				this.nameAndTypeCacheForFieldsAndMethods.put(key1, charArrayCache);
+			}
+		} else {
+			CharArrayCache charArrayCache = (CharArrayCache) key1Value;
+			index = charArrayCache.putIfAbsent(key2, value);
+		}
+		return index;
+	}
+	/**
+	 * @param key1 the given declaring class name
+	 * @param key2 the given field name or method selector
+	 * @param key3 the given signature
+	 * @param value the new index
+	 * @return the given index
+	 */
+	private int putInCacheIfAbsent(final char[] key1, final char[] key2, final char[] key3, int value) {
+		int index;
+		HashtableOfObject key1Value = (HashtableOfObject) this.methodsAndFieldsCache.get(key1);
+		if (key1Value == null) {
+			key1Value = new HashtableOfObject();
+			this.methodsAndFieldsCache.put(key1, key1Value);
+			CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value);
+			index = -value;
+			key1Value.put(key2, cachedIndexEntry);
+		} else {
+			Object key2Value = key1Value.get(key2);
+			if (key2Value == null) {
+				CachedIndexEntry cachedIndexEntry = new CachedIndexEntry(key3, value);
+				index = -value;
+				key1Value.put(key2, cachedIndexEntry);
+			} else if (key2Value instanceof CachedIndexEntry) {
+				// adding a second entry
+				CachedIndexEntry entry = (CachedIndexEntry) key2Value;
+				if (CharOperation.equals(key3, entry.signature)) {
+					index = entry.index;
+				} else {
+					CharArrayCache charArrayCache = new CharArrayCache();
+					charArrayCache.putIfAbsent(entry.signature, entry.index);
+					index = charArrayCache.putIfAbsent(key3, value);
+					key1Value.put(key2, charArrayCache);
+				}
+			} else {
+				CharArrayCache charArrayCache = (CharArrayCache) key2Value;
+				index = charArrayCache.putIfAbsent(key3, value);
+			}
+		}
+		return index;
+	}
+	/**
+	 * This method is used to clean the receiver in case of a clinit header is generated, but the
+	 * clinit has no code.
+	 * This implementation assumes that the clinit is the first method to be generated.
+	 * @see org.eclipse.jdt.internal.compiler.ast.TypeDeclaration#addClinit()
+	 */
+	public void resetForClinit(int constantPoolIndex, int constantPoolOffset) {
+		this.currentIndex = constantPoolIndex;
+		this.currentOffset = constantPoolOffset;
+		if (this.UTF8Cache.get(AttributeNamesConstants.CodeName) >= constantPoolIndex) {
+			this.UTF8Cache.remove(AttributeNamesConstants.CodeName);
+		}
+		if (this.UTF8Cache.get(ConstantPool.ClinitSignature) >= constantPoolIndex) {
+			this.UTF8Cache.remove(ConstantPool.ClinitSignature);
+		}
+		if (this.UTF8Cache.get(ConstantPool.Clinit) >= constantPoolIndex) {
+			this.UTF8Cache.remove(ConstantPool.Clinit);
+		}
+	}
+
+	/**
+	 * Resize the pool contents
+	 */
+	private final void resizePoolContents(int minimalSize) {
+		int length = this.poolContent.length;
+		int toAdd = length;
+		if (toAdd < minimalSize)
+			toAdd = minimalSize;
+		System.arraycopy(this.poolContent, 0, this.poolContent = new byte[length + toAdd], 0, length);
+	}
+	/**
+	 * Write a unsigned byte into the byte array
+	 *
+	 * @param value <CODE>int</CODE> The value to write into the byte array
+	 */
+	protected final void writeU1(int value) {
+		if (this.currentOffset + 1 >= this.poolContent.length) {
+			resizePoolContents(1);
+		}
+		this.poolContent[this.currentOffset++] = (byte) value;
+	}
+	/**
+	 * Write a unsigned byte into the byte array
+	 *
+	 * @param value <CODE>int</CODE> The value to write into the byte array
+	 */
+	protected final void writeU2(int value) {
+		if (this.currentOffset + 2 >= this.poolContent.length) {
+			resizePoolContents(2);
+		}
+		this.poolContent[this.currentOffset++] = (byte) (value >>> 8);
+		this.poolContent[this.currentOffset++] = (byte) value;
+	}
+	public void reset() {
+		if (this.doubleCache != null) this.doubleCache.clear();
+		if (this.floatCache != null) this.floatCache.clear();
+		if (this.intCache != null) this.intCache.clear();
+		if (this.longCache != null) this.longCache.clear();
+		this.UTF8Cache.clear();
+		this.stringCache.clear();
+		this.methodsAndFieldsCache.clear();
+		this.classCache.clear();
+		this.nameAndTypeCacheForFieldsAndMethods.clear();
+		this.currentIndex = 1;
+		this.currentOffset = 0;
+	}
+	public void resetForAttributeName(char[] attributeName, int constantPoolIndex, int constantPoolOffset) {
+		this.currentIndex = constantPoolIndex;
+		this.currentOffset = constantPoolOffset;
+		if (this.UTF8Cache.get(attributeName) >= constantPoolIndex) {
+			this.UTF8Cache.remove(attributeName);
+		}
+	}
 }
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 5328c25..7c26397 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -16,14 +16,16 @@
 public class ExceptionLabel extends Label {
 
 	public int ranges[] = {POS_NOT_SET,POS_NOT_SET};
-	public int count = 0; // incremented each time placeStart or placeEnd is called
+	private int count = 0; // incremented each time placeStart or placeEnd is called
 	public TypeBinding exceptionType;
 
 public ExceptionLabel(CodeStream codeStream, TypeBinding exceptionType) {
 	super(codeStream);
 	this.exceptionType = exceptionType;
 }
-
+public int getCount() {
+	return this.count;
+}
 public void place() {
 	// register the handler inside the codeStream then normal place
 	this.codeStream.registerExceptionHandler(this);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
new file mode 100644
index 0000000..2d0fc54
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/MultiCatchExceptionLabel.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made 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.codegen;
+
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class MultiCatchExceptionLabel extends ExceptionLabel {
+
+	ExceptionLabel[] exceptionLabels;
+
+	public MultiCatchExceptionLabel(CodeStream codeStream, TypeBinding exceptionType) {
+		super(codeStream, exceptionType);
+	}
+	
+	public void initialize(UnionTypeReference typeReference) {
+		TypeReference[] typeReferences = typeReference.typeReferences;
+		int length = typeReferences.length;
+		this.exceptionLabels = new ExceptionLabel[length];
+		for (int i = 0; i < length; i++) {
+			this.exceptionLabels[i] = new ExceptionLabel(this.codeStream, typeReferences[i].resolvedType);
+		}
+	}
+	public void place() {
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			this.exceptionLabels[i].place();
+		}
+	}
+	public void placeEnd() {
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			this.exceptionLabels[i].placeEnd();
+		}
+	}
+	public void placeStart() {
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			this.exceptionLabels[i].placeStart();
+		}
+	}
+	public int getCount() {
+		int temp = 0;
+		for (int i = 0, max = this.exceptionLabels.length; i < max; i++) {
+			temp += this.exceptionLabels[i].getCount();
+		}
+		return temp;
+	}
+}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
index 9dd6960..14b8845 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -19,13 +19,16 @@
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ClassFile;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+import org.eclipse.jdt.internal.compiler.problem.AbortMethod;
 
 public class StackMapFrameCodeStream extends CodeStream {
 	public static class ExceptionMarker implements Comparable {
@@ -347,6 +350,14 @@
 		this.stackDepth = savedStackDepth;
 	}
 }
+public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
+	int currentPosition = this.position;
+	super.generateOuterAccess(mappingSequence, invocationSite, target, scope);
+	if (currentPosition == this.position) {
+		// no code has been generate during outer access => no enclosing instance is available
+		throw new AbortMethod(scope.referenceCompilationUnit().compilationResult, null);
+	}
+}
 public ExceptionMarker[] getExceptionMarkers() {
 	Set exceptionMarkerSet = this.exceptionMarkers;
 	if (this.exceptionMarkers == null) return null;
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 c6b591e..c52665f 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
@@ -14,10 +14,14 @@
 
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
 import org.eclipse.jdt.internal.compiler.ast.TryStatement;
+import org.eclipse.jdt.internal.compiler.ast.TypeReference;
 import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -36,7 +40,8 @@
 	public ReferenceBinding[] handledExceptions;
 	int[] isReached;
 	int[] isNeeded;
-	UnconditionalFlowInfo[] initsOnExceptions;
+	// WARNING: This is an array that maps to catch blocks, not caught exceptions (which could be more than catch blocks in a multi-catch block)
+	UnconditionalFlowInfo[] initsOnExceptions; 
 	ObjectCache indexes = new ObjectCache();
 	boolean isMethodContext;
 
@@ -46,10 +51,26 @@
 	// for dealing with anonymous constructor thrown exceptions
 	public ArrayList extendedExceptions;
 
+	private static final Argument[] NO_ARGUMENTS = new Argument[0];
+	public  Argument [] catchArguments;
+
+	private int[] exceptionToCatchBlockMap;
+
+public ExceptionHandlingFlowContext(
+			FlowContext parent,
+			ASTNode associatedNode,
+			ReferenceBinding[] handledExceptions,
+			FlowContext initializationParent,
+			BlockScope scope,
+			UnconditionalFlowInfo flowInfo) {
+	this(parent, associatedNode, handledExceptions, null, NO_ARGUMENTS, initializationParent, scope, flowInfo);
+}
 public ExceptionHandlingFlowContext(
 		FlowContext parent,
 		ASTNode associatedNode,
 		ReferenceBinding[] handledExceptions,
+		int [] exceptionToCatchBlockMap,
+		Argument [] catchArguments,
 		FlowContext initializationParent,
 		BlockScope scope,
 		UnconditionalFlowInfo flowInfo) {
@@ -57,6 +78,8 @@
 	super(parent, associatedNode);
 	this.isMethodContext = scope == scope.methodScope();
 	this.handledExceptions = handledExceptions;
+	this.catchArguments = catchArguments;
+	this.exceptionToCatchBlockMap = exceptionToCatchBlockMap;
 	int count = handledExceptions.length, cacheSize = (count / ExceptionHandlingFlowContext.BitCacheSize) + 1;
 	this.isReached = new int[cacheSize]; // none is reached by default
 	this.isNeeded = new int[cacheSize]; // none is needed by default
@@ -65,6 +88,7 @@
 		!this.isMethodContext || scope.compilerOptions().reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable;
 	for (int i = 0; i < count; i++) {
 		ReferenceBinding handledException = handledExceptions[i];
+		int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[i] : i;
 		this.indexes.put(handledException, i); // key type  -> value index
 		if (handledException.isUncheckedException(true)) {
 			if (markExceptionsAndThrowableAsReached ||
@@ -72,16 +96,16 @@
 					handledException.id != TypeIds.T_JavaLangException) {
 				this.isReached[i / ExceptionHandlingFlowContext.BitCacheSize] |= 1 << (i % ExceptionHandlingFlowContext.BitCacheSize);
 			}
-			this.initsOnExceptions[i] = flowInfo.unconditionalCopy();
+			this.initsOnExceptions[catchBlock] = flowInfo.unconditionalCopy();
 		} else {
-			this.initsOnExceptions[i] = FlowInfo.DEAD_END;
+			this.initsOnExceptions[catchBlock] = FlowInfo.DEAD_END;
 		}
 	}
 	if (!this.isMethodContext) {
 		System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize);
 	}
 	this.initsOnReturn = FlowInfo.DEAD_END;
-	this.	initializationParent = initializationParent;
+	this.initializationParent = initializationParent;
 }
 
 public void complainIfUnusedExceptionHandlers(AbstractMethodDeclaration method) {
@@ -127,24 +151,41 @@
 
 public void complainIfUnusedExceptionHandlers(BlockScope scope,TryStatement tryStatement) {
 	// report errors for unreachable exception handlers
-	for (int i = 0, count = this.handledExceptions.length; i < count; i++) {
-		int index = this.indexes.get(this.handledExceptions[i]);
+	for (int index = 0, count = this.handledExceptions.length; index < count; index++) {
 		int cacheIndex = index / ExceptionHandlingFlowContext.BitCacheSize;
 		int bitMask = 1 << (index % ExceptionHandlingFlowContext.BitCacheSize);
 		if ((this.isReached[cacheIndex] & bitMask) == 0) {
 			scope.problemReporter().unreachableCatchBlock(
 				this.handledExceptions[index],
-				tryStatement.catchArguments[index].type);
+				getExceptionType(index));
 		} else {
 			if ((this.isNeeded[cacheIndex] & bitMask) == 0) {
 				scope.problemReporter().hiddenCatchBlock(
 					this.handledExceptions[index],
-					tryStatement.catchArguments[index].type);
+					getExceptionType(index));
 			}
 		}
 	}
 }
 
+private ASTNode getExceptionType(int index) {	
+	if (this.exceptionToCatchBlockMap == null) {
+		return this.catchArguments[index].type;
+	}
+	int catchBlock = this.exceptionToCatchBlockMap[index];
+	ASTNode node = this.catchArguments[catchBlock].type;
+	if (node instanceof UnionTypeReference) {
+		TypeReference[] typeRefs = ((UnionTypeReference)node).typeReferences;
+		for (int i = 0, len = typeRefs.length; i < len; i++) {
+			TypeReference typeRef = typeRefs[i];
+			if (typeRef.resolvedType == this.handledExceptions[index]) return typeRef;
+		}	
+	} 
+	return node;
+}
+
+
+
 public String individualToString() {
 	StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
 	int length = this.handledExceptions.length;
@@ -161,17 +202,16 @@
 		} else {
 			buffer.append("-not reached"); //$NON-NLS-1$
 		}
-		buffer.append('-').append(this.initsOnExceptions[i].toString()).append(']');
+		int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[i] : i;
+		buffer.append('-').append(this.initsOnExceptions[catchBlock].toString()).append(']');
 	}
 	buffer.append("[initsOnReturn -").append(this.initsOnReturn.toString()).append(']'); //$NON-NLS-1$
 	return buffer.toString();
 }
 
-public UnconditionalFlowInfo initsOnException(ReferenceBinding exceptionType) {
-	int index;
-	if ((index = this.indexes.get(exceptionType)) < 0) {
-		return FlowInfo.DEAD_END;
-	}
+// WARNING: index is the catch block index as in the program order, before any normalization is
+// applied for multi catch
+public UnconditionalFlowInfo initsOnException(int index) {
 	return this.initsOnExceptions[index];
 }
 
@@ -213,6 +253,7 @@
 		ReferenceBinding exceptionType,
 		UnconditionalFlowInfo flowInfo,
 		TypeBinding raisedException,
+		TypeBinding caughtException,
 		ASTNode invocationSite,
 		boolean wasAlreadyDefinitelyCaught) {
 
@@ -223,10 +264,14 @@
 		this.isNeeded[cacheIndex] |= bitMask;
 	}
 	this.isReached[cacheIndex] |= bitMask;
-
-	this.initsOnExceptions[index] =
-		(this.initsOnExceptions[index].tagBits & FlowInfo.UNREACHABLE) == 0 ?
-			this.initsOnExceptions[index].mergedWith(flowInfo):
+	int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[index] : index;
+	if (caughtException != null && this.catchArguments != null && this.catchArguments.length > 0 && !wasAlreadyDefinitelyCaught) {
+		CatchParameterBinding catchParameter = (CatchParameterBinding) this.catchArguments[catchBlock].binding;
+		catchParameter.setPreciseType(caughtException);
+	}
+	this.initsOnExceptions[catchBlock] =
+		(this.initsOnExceptions[catchBlock].tagBits & FlowInfo.UNREACHABLE) == 0 ?
+			this.initsOnExceptions[catchBlock].mergedWith(flowInfo):
 			flowInfo.unconditionalCopy();
 }
 
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 2ce915a..e768ff0 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
@@ -4,7 +4,7 @@
  * are made 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
  *******************************************************************************/
@@ -17,12 +17,16 @@
 import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
 import org.eclipse.jdt.internal.compiler.ast.Reference;
+import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
 import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
+import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
 import org.eclipse.jdt.internal.compiler.ast.TryStatement;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.CatchParameterBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
@@ -87,6 +91,14 @@
 }
 
 public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
+	checkExceptionHandlers(raisedException, location, flowInfo, scope, false);
+}
+/**
+ * @param isExceptionOnAutoClose This is for checking exception handlers for exceptions raised during the
+ * auto close of resources inside a try with resources statement. (Relevant for
+ * source levels 1.7 and above only)
+ */
+public void checkExceptionHandlers(TypeBinding raisedException, ASTNode location, FlowInfo flowInfo, BlockScope scope, boolean isExceptionOnAutoClose) {
 	// LIGHT-VERSION OF THE EQUIVALENT WITH AN ARRAY OF EXCEPTIONS
 	// check that all the argument exception types are handled
 	// JDK Compatible implementation - when an exception type is thrown,
@@ -94,6 +106,16 @@
 	// until the point where it is safely handled (Smarter - see comment at the end)
 	FlowContext traversedContext = this;
 	ArrayList abruptlyExitedLoops = null;
+	if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7 && location instanceof ThrowStatement) {
+		Expression throwExpression = ((ThrowStatement)location).exception;
+		LocalVariableBinding throwArgBinding = throwExpression.localVariableBinding();
+		if (throwExpression instanceof SingleNameReference // https://bugs.eclipse.org/bugs/show_bug.cgi?id=350361 
+				&& throwArgBinding instanceof CatchParameterBinding && throwArgBinding.isEffectivelyFinal()) {
+			CatchParameterBinding parameter = (CatchParameterBinding) throwArgBinding;
+			checkExceptionHandlers(parameter.getPreciseTypes(), location, flowInfo, scope);
+			return;
+		}
+	}
 	while (traversedContext != null) {
 		SubRoutineStatement sub;
 		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
@@ -129,6 +151,7 @@
 								caughtException,
 								flowInfo.unconditionalInits(),
 								raisedException,
+								raisedException, // precise exception that will be caught
 								location,
 								definitelyCaught);
 							// was it already definitely caught ?
@@ -139,6 +162,7 @@
 								caughtException,
 								flowInfo.unconditionalInits(),
 								raisedException,
+								caughtException,
 								location,
 								false);
 							// was not caught already per construction
@@ -183,7 +207,11 @@
 		traversedContext = traversedContext.parent;
 	}
 	// if reaches this point, then there are some remaining unhandled exception types.
-	scope.problemReporter().unhandledException(raisedException, location);
+	if (isExceptionOnAutoClose) {
+		scope.problemReporter().unhandledExceptionFromAutoClose(raisedException, location);
+	} else {
+		scope.problemReporter().unhandledException(raisedException, location);
+	}
 }
 
 public void checkExceptionHandlers(TypeBinding[] raisedExceptions, ASTNode location, FlowInfo flowInfo, BlockScope scope) {
@@ -246,6 +274,7 @@
 										caughtException,
 										flowInfo.unconditionalInits(),
 										raisedException,
+										raisedException, // precise exception that will be caught
 										location,
 										locallyCaught[raisedIndex]);
 									// was already definitely caught ?
@@ -260,6 +289,7 @@
 										caughtException,
 										flowInfo.unconditionalInits(),
 										raisedException,
+										caughtException, 
 										location,
 										false);
 									// was not caught already per construction
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 391c59a..547086b 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, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *******************************************************************************/
@@ -65,6 +65,7 @@
 		ReferenceBinding exceptionType,
 		UnconditionalFlowInfo flowInfo,
 		TypeBinding raisedException,
+		TypeBinding caughtException,
 		ASTNode invocationSite,
 		boolean wasMasked) {
 
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 e243384..886fea6 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Stephan Herrmann - contribution for Bug 336428 - [compiler][null] bogus warning "redundant null check" in condition of do {} while() loop
@@ -58,8 +58,8 @@
 		}
 		void simulateThrowAfterLoopBack(FlowInfo flowInfo) {
 			this.catchingContext.recordHandlingException(this.caughtException,
-					flowInfo.unconditionalInits(), null, // raised exception, irrelevant here
-					null, /* invocation site, irrelevant here */ true // we have no business altering the needed status.
+					flowInfo.unconditionalInits(), null, // raised exception, irrelevant here,
+					null, null, /* invocation site, irrelevant here */ true // we have no business altering the needed status.
 					);
 		}
 	}
@@ -520,7 +520,7 @@
 						flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
 					}
 				}
-			} else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local) && !flowInfo.isPotentiallyUnknown(local)) {    
+			} else if (this.upstreamNullFlowInfo.isDefinitelyNonNull(local) && !flowInfo.isPotentiallyNull(local) && !flowInfo.isPotentiallyUnknown(local)) {
 				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=291418
 				flowInfo.markAsDefinitelyNonNull(local);
 				if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) {
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 5f3c6b6..6213217 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
@@ -145,6 +145,7 @@
 	public static final String OPTION_IncludeNullInfoFromAsserts = "org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts";  //$NON-NLS-1$
 	public static final String OPTION_ReportMethodCanBeStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic";  //$NON-NLS-1$
 	public static final String OPTION_ReportMethodCanBePotentiallyStatic = "org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic";  //$NON-NLS-1$
+	public static final String OPTION_ReportRedundantSpecificationOfTypeArguments =  "org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments"; //$NON-NLS-1$
 
 //{ObjectTeams: sync with constants in OTDTPlugin:
 	public static final String OPTION_ReportNotExactlyOneBasecall =
@@ -315,6 +316,7 @@
 	public static final int UnusedObjectAllocation = IrritantSet.GROUP2 | ASTNode.Bit4;
 	public static final int MethodCanBeStatic = IrritantSet.GROUP2 | ASTNode.Bit5;
 	public static final int MethodCanBePotentiallyStatic = IrritantSet.GROUP2 | ASTNode.Bit6;
+	public static final int RedundantSpecificationOfTypeArguments = IrritantSet.GROUP2 | ASTNode.Bit7;
 
 //{ObjectTeams: OT/J specific problems/irritants:
 	public static final int OTJFlag = IrritantSet.GROUP3;
@@ -678,6 +680,8 @@
 				return OPTION_ReportMethodCanBeStatic;
 			case MethodCanBePotentiallyStatic :
 				return OPTION_ReportMethodCanBePotentiallyStatic;
+			case RedundantSpecificationOfTypeArguments :
+				return OPTION_ReportRedundantSpecificationOfTypeArguments;
 //{ObjectTeams:
 			case NotExactlyOneBasecall :
 				return OPTION_ReportNotExactlyOneBasecall;
@@ -859,6 +863,7 @@
 			OPTION_ReportRawTypeReference,
 			OPTION_ReportRedundantNullCheck,
 			OPTION_ReportRedundantSuperinterface,
+			OPTION_ReportRedundantSpecificationOfTypeArguments,
 			OPTION_ReportSpecialParameterHidingField,
 			OPTION_ReportSyntheticAccessEmulation,
 			OPTION_ReportTasks,
@@ -963,6 +968,7 @@
 			case UnusedDeclaredThrownException :
 			case DeadCode :
 			case UnusedObjectAllocation :
+			case RedundantSpecificationOfTypeArguments :
 				return "unused"; //$NON-NLS-1$
 			case DiscouragedReference :
 			case ForbiddenReference :
@@ -1275,6 +1281,7 @@
 		optionsMap.put(OPTION_IncludeNullInfoFromAsserts, this.includeNullInfoFromAsserts ? ENABLED : DISABLED);
 		optionsMap.put(OPTION_ReportMethodCanBeStatic, getSeverityString(MethodCanBeStatic));
 		optionsMap.put(OPTION_ReportMethodCanBePotentiallyStatic, getSeverityString(MethodCanBePotentiallyStatic));
+		optionsMap.put(OPTION_ReportRedundantSpecificationOfTypeArguments, getSeverityString(RedundantSpecificationOfTypeArguments));
 //{ObjectTeams:
 		optionsMap.put(OPTION_Decapsulation, this.decapsulation);
 
@@ -1736,6 +1743,7 @@
 		if ((optionValue = optionsMap.get(OPTION_ReportUnusedObjectAllocation)) != null) updateSeverity(UnusedObjectAllocation, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBeStatic)) != null) updateSeverity(MethodCanBeStatic, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportMethodCanBePotentiallyStatic)) != null) updateSeverity(MethodCanBePotentiallyStatic, optionValue);
+		if ((optionValue = optionsMap.get(OPTION_ReportRedundantSpecificationOfTypeArguments)) != null) updateSeverity(RedundantSpecificationOfTypeArguments, optionValue);
 //{ObjectTeams:
 		if ((optionValue = optionsMap.get(OPTION_ReportNotExactlyOneBasecall)) != null) updateSeverity(NotExactlyOneBasecall, optionValue);
 		if ((optionValue = optionsMap.get(OPTION_ReportBaseclassCycle)) != null) updateSeverity(BaseclassCycle, optionValue);
@@ -1996,6 +2004,7 @@
 		buf.append("\n\t- unused object allocation: ").append(getSeverityString(UnusedObjectAllocation)); //$NON-NLS-1$
 		buf.append("\n\t- method can be static: ").append(getSeverityString(MethodCanBeStatic)); //$NON-NLS-1$
 		buf.append("\n\t- method can be potentially static: ").append(getSeverityString(MethodCanBePotentiallyStatic)); //$NON-NLS-1$
+		buf.append("\n\t- redundant specification of type arguments: ").append(getSeverityString(RedundantSpecificationOfTypeArguments)); //$NON-NLS-1$
 //{ObjectTeams
 		buf.append("\n\t- decapsulation : ").append(this.decapsulation); //$NON-NLS-1$
 		buf.append("\n\t- report if not exactly one basecall in callin method : ").append(getSeverityString(NotExactlyOneBasecall)); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index eb3dd3d..38e7b06 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -195,7 +195,8 @@
 			.set(CompilerOptions.UnusedTypeArguments)
 			.set(CompilerOptions.RedundantSuperinterface)
 			.set(CompilerOptions.DeadCode)
-			.set(CompilerOptions.UnusedObjectAllocation);
+			.set(CompilerOptions.UnusedObjectAllocation)
+			.set(CompilerOptions.RedundantSpecificationOfTypeArguments);
 		STATIC_METHOD
 		    .set(CompilerOptions.MethodCanBePotentiallyStatic);
 		String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
index 271fe98..6fe4141 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -47,6 +47,10 @@
 		count++;
 	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
 		count++;
+	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0)
+		count++;
+	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0)
+		count++;
 	if (count == 0)
 		return recordedAnnotations;
 
@@ -67,9 +71,23 @@
 		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, env);
 	if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0)
 		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, env);
+	if ((annotationTagBits & TagBits.AnnotationPolymorphicSignature) != 0)
+		result[index++] = buildMarkerAnnotationForMemberType(TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE, env);
+	if ((annotationTagBits & TagBits.AnnotationSafeVarargs) != 0)
+		result[index++] = buildMarkerAnnotation(TypeConstants.JAVA_LANG_SAFEVARARGS, env);
 	return result;
 }
 
+private static AnnotationBinding buildMarkerAnnotationForMemberType(char[][] compoundName, LookupEnvironment env) {
+	ReferenceBinding type = env.getResolvedType(compoundName, null);
+	// since this is a member type name using '$' the return binding is a
+	// problem reference binding with reason ProblemReasons.InternalNameProvided
+	if (!type.isValidBinding()) {
+		type = ((ProblemReferenceBinding) type).closestMatch;
+	}
+	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
+}
+
 private static AnnotationBinding buildMarkerAnnotation(char[][] compoundName, LookupEnvironment env) {
 	ReferenceBinding type = env.getResolvedType(compoundName, null);
 	return env.createAnnotation(type, Binding.NO_ELEMENT_VALUE_PAIRS);
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 5b29470..d5c5e96 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
@@ -994,8 +994,10 @@
 	int max = -1;
 	if (this.shiftScopes != null){
 		for (int i = 0, length = this.shiftScopes.length; i < length; i++){
-			int subMaxOffset = this.shiftScopes[i].maxOffset;
-			if (subMaxOffset > max) max = subMaxOffset;
+			if (this.shiftScopes[i] != null) {
+				int subMaxOffset = this.shiftScopes[i].maxOffset;
+				if (subMaxOffset > max) max = subMaxOffset;
+			}
 		}
 	}
 	return max;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
new file mode 100644
index 0000000..289655c
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CatchParameterBinding.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made 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.internal.compiler.ast.LocalDeclaration;
+
+public class CatchParameterBinding extends LocalVariableBinding {
+	
+	TypeBinding [] preciseTypes = Binding.NO_EXCEPTIONS;  // the catch block can be entered with the parameters set to these types.
+	
+	public CatchParameterBinding(LocalDeclaration declaration, TypeBinding type, int modifiers, boolean isArgument) {
+		super(declaration, type, modifiers, isArgument);
+	}
+	
+	public TypeBinding [] getPreciseTypes() {
+		return this.preciseTypes;
+	}
+
+	public void setPreciseType(TypeBinding raisedException) {
+		int length = this.preciseTypes.length;
+		for (int i = 0; i < length; ++i) {
+			if (this.preciseTypes[i] == raisedException)
+				return;
+		}
+		System.arraycopy(this.preciseTypes, 0, this.preciseTypes = new TypeBinding [length + 1], 0, length);
+		this.preciseTypes[length] = raisedException;
+		return;
+	}
+}
\ No newline at end of file
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 d331b9e..5802d3d 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
@@ -7,7 +7,9 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for 
+ *     						Bug 328281 - visibility leaks not detected when analyzing unused field in private class
+ *     						Bug 300576 - NPE Computing type hierarchy when compliance doesn't match libraries
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -1583,6 +1585,11 @@
 	private boolean connectEnumSuperclass() {
 		SourceTypeBinding sourceType = this.referenceContext.binding;
 		ReferenceBinding rootEnumType = getJavaLangEnum();
+		if ((rootEnumType.tagBits & TagBits.HasMissingType) != 0) {
+			sourceType.tagBits |= TagBits.HierarchyHasProblems; // mark missing supertpye
+			sourceType.superclass = rootEnumType;
+			return false;
+		}
 		boolean foundCycle = detectHierarchyCycle(sourceType, rootEnumType, null);
 		// arity check for well-known Enum<E>
 		TypeVariableBinding[] refTypeVariables = rootEnumType.typeVariables();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java
index 2f01780..f0e03bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
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 0a55b83..b7e7794 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, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
@@ -53,6 +53,7 @@
 	public LocalVariableBinding(char[] name, TypeBinding type, int modifiers, boolean isArgument) {
 		super(name, type, modifiers, isArgument ? Constant.NotAConstant : null);
 		if (isArgument) this.tagBits |= TagBits.IsArgument;
+		this.tagBits |= TagBits.IsEffectivelyFinal;
 	}
 
 	// regular local variable or argument
@@ -60,6 +61,7 @@
 
 		this(declaration.name, type, modifiers, isArgument);
 		this.declaration = declaration;
+		this.tagBits |= TagBits.IsEffectivelyFinal;
 	}
 //{ObjectTeams: support anchor paths:
 	protected TeamAnchor getClone() {
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 cc83060..dfe33bc 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
@@ -112,6 +112,9 @@
 	private SimpleLookupTable uniqueRawTypeBindings;
 	private SimpleLookupTable uniqueWildcardBindings;
 	private SimpleLookupTable uniqueParameterizedGenericMethodBindings;
+	
+	// key is a string with the method selector value is an array of method bindings
+	private SimpleLookupTable uniquePolymorphicMethodBindings;
 	private SimpleLookupTable uniqueGetClassMethodBinding; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=300734
 
 	public CompilationUnitDeclaration unitBeingCompleted = null; // only set while completing units
@@ -156,6 +159,7 @@
 	this.uniqueRawTypeBindings = new SimpleLookupTable(3);
 	this.uniqueWildcardBindings = new SimpleLookupTable(3);
 	this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
+	this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3);
 	this.missingTypes = null;
 	this.accessRestrictions = new HashMap(3);
 	this.classFilePool = ClassFilePool.newInstance();
@@ -984,7 +988,90 @@
 	cachedInfo[index] = parameterizedGenericMethod;
 	return parameterizedGenericMethod;
 }
-
+public PolymorphicMethodBinding createPolymorphicMethod(MethodBinding originalPolymorphicMethod, TypeBinding[] parameters) {
+	// cached info is array of already created polymorphic methods for this type
+	String key = new String(originalPolymorphicMethod.selector);
+	PolymorphicMethodBinding[] cachedInfo = (PolymorphicMethodBinding[]) this.uniquePolymorphicMethodBindings.get(key);
+	int parametersLength = parameters == null ? 0: parameters.length;
+	TypeBinding[] parametersTypeBinding = new TypeBinding[parametersLength]; 
+	for (int i = 0; i < parametersLength; i++) {
+		TypeBinding parameterTypeBinding = parameters[i];
+		if (parameterTypeBinding.id == TypeIds.T_null) {
+			parametersTypeBinding[i] = getType(JAVA_LANG_VOID);
+		} else {
+			parametersTypeBinding[i] = parameterTypeBinding.erasure();
+		}
+	}
+	boolean needToGrow = false;
+	int index = 0;
+	if (cachedInfo != null) {
+		nextCachedMethod :
+			// iterate existing polymorphic method for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++) {
+				PolymorphicMethodBinding cachedMethod = cachedInfo[index];
+				if (cachedMethod == null) {
+					break nextCachedMethod;
+				}
+				if (cachedMethod.matches(parametersTypeBinding, originalPolymorphicMethod.returnType)) {
+					return cachedMethod;
+				}
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new PolymorphicMethodBinding[5];
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length) {
+		System.arraycopy(cachedInfo, 0, cachedInfo = new PolymorphicMethodBinding[length*2], 0, length);
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// add new binding
+	PolymorphicMethodBinding polymorphicMethod = new PolymorphicMethodBinding(
+			originalPolymorphicMethod,
+			parametersTypeBinding);
+	cachedInfo[index] = polymorphicMethod;
+	return polymorphicMethod;
+}
+public MethodBinding updatePolymorphicMethodReturnType(PolymorphicMethodBinding binding, TypeBinding typeBinding) {
+	// update the return type to be the given return type, but reuse existing binding if one can match
+	String key = new String(binding.selector);
+	PolymorphicMethodBinding[] cachedInfo = (PolymorphicMethodBinding[]) this.uniquePolymorphicMethodBindings.get(key);
+	boolean needToGrow = false;
+	int index = 0;
+	TypeBinding[] parameters = binding.parameters;
+	if (cachedInfo != null) {
+		nextCachedMethod :
+			// iterate existing polymorphic method for reusing one with same type arguments if any
+			for (int max = cachedInfo.length; index < max; index++) {
+				PolymorphicMethodBinding cachedMethod = cachedInfo[index];
+				if (cachedMethod == null) {
+					break nextCachedMethod;
+				}
+				if (cachedMethod.matches(parameters, typeBinding)) {
+					return cachedMethod;
+				}
+		}
+		needToGrow = true;
+	} else {
+		cachedInfo = new PolymorphicMethodBinding[5];
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// grow cache ?
+	int length = cachedInfo.length;
+	if (needToGrow && index == length) {
+		System.arraycopy(cachedInfo, 0, cachedInfo = new PolymorphicMethodBinding[length*2], 0, length);
+		this.uniquePolymorphicMethodBindings.put(key, cachedInfo);
+	}
+	// add new binding
+	PolymorphicMethodBinding polymorphicMethod = new PolymorphicMethodBinding(
+			binding.original(),
+			typeBinding,
+			parameters);
+	cachedInfo[index] = polymorphicMethod;
+	return polymorphicMethod;
+}
 public ParameterizedMethodBinding createGetClassMethod(TypeBinding receiverType, MethodBinding originalMethod, Scope scope) {
 	// see if we have already cached this method for the given receiver type.
 	ParameterizedMethodBinding retVal = null;
@@ -1631,6 +1718,7 @@
 	this.uniqueRawTypeBindings = new SimpleLookupTable(3);
 	this.uniqueWildcardBindings = new SimpleLookupTable(3);
 	this.uniqueParameterizedGenericMethodBindings = new SimpleLookupTable(3);
+	this.uniquePolymorphicMethodBindings = new SimpleLookupTable(3);
 	this.uniqueGetClassMethodBinding = null;
 	this.missingTypes = null;
 	this.typesBeingConnected = new HashSet();
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 b488340..51ec3a4 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -1184,10 +1184,12 @@
 
 /* Answer true if the receiver method has varargs
 */
-public final boolean isVarargs() {
+public boolean isVarargs() {
 	return (this.modifiers & ClassFileConstants.AccVarargs) != 0;
 }
-
+public boolean isPolymorphic() {
+	return false;
+}
 /* Answer true if the receiver's declaring type is deprecated (or any of its enclosing types)
 */
 public final boolean isViewedAsDeprecated() {
@@ -1201,7 +1203,7 @@
 */
 
 /**
- * Returns the original method (as opposed to parameterized instances)
+ * Returns the original method (as opposed to parameterized/polymorphic instances)
  */
 public MethodBinding original() {
 	return this;
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 2de1a5d..6437df7 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
@@ -283,7 +283,7 @@
 	//		class A implements I<Integer> { public void test(Integer i) {} }
 	//		class B extends A { public void test(Comparable i) {} }
 
-	if (currentMethod.declaringClass.isInterface() || inheritedMethod.isStatic()) return;
+	if (inheritedMethod.isStatic()) return;
 
 	if (!detectNameClash(currentMethod, inheritedMethod, false)) { // check up the hierarchy for skipped inherited methods
 		TypeBinding[] currentParams = currentMethod.parameters;
@@ -356,16 +356,6 @@
 	}
 }
 void checkInheritedMethods(MethodBinding inheritedMethod, MethodBinding otherInheritedMethod) {
-	// sent from checkMethods() to compare 2 inherited methods that are not 'equal'
-	if (inheritedMethod.declaringClass.erasure() == otherInheritedMethod.declaringClass.erasure()) {
-		boolean areDuplicates = inheritedMethod.hasSubstitutedParameters() && otherInheritedMethod.hasSubstitutedParameters()
-			? inheritedMethod.areParametersEqual(otherInheritedMethod)
-			: inheritedMethod.areParameterErasuresEqual(otherInheritedMethod);
-		if (areDuplicates) {
-			problemReporter().duplicateInheritedMethods(this.type, inheritedMethod, otherInheritedMethod);
-			return;
-		}
-	}
 
 	// the 2 inherited methods clash because of a parameterized type overrides a raw type
 	//		interface I { void foo(A a); }
@@ -381,70 +371,32 @@
 
 	detectInheritedNameClash(inheritedMethod.original(), otherInheritedMethod.original());
 }
+// 8.4.8.4
 void checkInheritedMethods(MethodBinding[] methods, int length) {
-	int count = length;
-	int[] skip = new int[count];
-	nextMethod : for (int i = 0, l = length - 1; i < l; i++) {
-		if (skip[i] == -1) continue nextMethod;
-		MethodBinding method = methods[i];
-		MethodBinding[] duplicates = null;
-		for (int j = i + 1; j <= l; j++) {
-			MethodBinding method2 = methods[j];
-			if (method.declaringClass == method2.declaringClass && areMethodsCompatible(method, method2)) {
-				skip[j] = -1;
-				if (duplicates == null)
-					duplicates = new MethodBinding[length];
-				duplicates[j] = method2;
+	boolean continueInvestigation = true;
+	MethodBinding concreteMethod = null;
+	for (int i = 0; i < length; i++) {
+		if (!methods[i].isAbstract()) {
+			if (concreteMethod != null) {
+				problemReporter().duplicateInheritedMethods(this.type, concreteMethod, methods[i]);
+				continueInvestigation = false;
 			}
-		}
-		if (duplicates != null) {
-			// found an inherited ParameterizedType that defines duplicate methods
-			// if all methods are abstract or more than 1 concrete method exists, then consider them to be duplicates
-			// if a single concrete method 'implements' the abstract methods, then do not report a duplicate error
-			int concreteCount = method.isAbstract() ? 0 : 1;
-			MethodBinding methodToKeep = method; // if a concrete method exists, keep it, otherwise keep the first method
-			for (int m = 0, s = duplicates.length; m < s; m++) {
-				if (duplicates[m] != null) {
-					if (!duplicates[m].isAbstract()) {
-						methodToKeep = duplicates[m];
-						concreteCount++;
-					}
-				}
-			}
-			if (concreteCount != 1) {
-				for (int m = 0, s = duplicates.length; m < s; m++) {
-					if (duplicates[m] != null) {
-						problemReporter().duplicateInheritedMethods(this.type, method, duplicates[m]);
-						count--;
-						if (methodToKeep == duplicates[m])
-							methods[i] = null;
-						else
-							methods[m] = null;
-					}
-				}
-			}
+			concreteMethod = methods[i];
 		}
 	}
-	if (count < length) {
-		if (count == 1) return; // no need to continue since only 1 inherited method is left
-		MethodBinding[] newMethods = new MethodBinding[count];
-		for (int i = length; --i >= 0;)
-			if (methods[i] != null)
-				newMethods[--count] = methods[i];
-		methods = newMethods;
-		length = newMethods.length;
+	if (continueInvestigation) {
+		super.checkInheritedMethods(methods, length);
 	}
-
-	super.checkInheritedMethods(methods, length);
 }
 boolean checkInheritedReturnTypes(MethodBinding method, MethodBinding otherMethod) {
 	if (areReturnTypesCompatible(method, otherMethod)) return true;
 
-	if (!this.type.isInterface())
-		if (method.declaringClass.isClass() || !this.type.implementsInterface(method.declaringClass, false))
-			if (otherMethod.declaringClass.isClass() || !this.type.implementsInterface(otherMethod.declaringClass, false))
-				return true; // do not complain since the superclass already got blamed
-
+	/* We used to have some checks here to see if we would have already blamed the super type and if so avoid blaming
+	   the current type again. I have gotten rid of them as they in fact short circuit error reporting in cases where
+	   they should not. This means that occasionally we would report the error twice - the diagnostics is valid however,
+	   albeit arguably redundant. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=334313. For an example of a test
+	   where we do this extra reporting see org.eclipse.jdt.core.tests.compiler.regression.MethodVerifyTest.test159()
+	 */
 	// check to see if this is just a warning, if so report it & skip to next method
 	if (isUnsafeReturnTypeOverride(method, otherMethod)) {
 		if (!method.declaringClass.implementsInterface(otherMethod.declaringClass, false))
@@ -581,8 +533,8 @@
 
 		int index = -1;
 		int inheritedLength = inherited.length;
-		MethodBinding[] matchingInherited = new MethodBinding[inherited.length];
-		MethodBinding[] foundMatch = new MethodBinding[inherited.length]; // null is no match, otherwise value is matching currentMethod
+		MethodBinding[] matchingInherited = new MethodBinding[inheritedLength];
+		MethodBinding[] foundMatch = new MethodBinding[inheritedLength]; // null is no match, otherwise value is matching currentMethod
 		if (current != null) {
 			for (int i = 0, length1 = current.length; i < length1; i++) {
 				MethodBinding currentMethod = current[i];
@@ -684,8 +636,7 @@
 				}
 				otherInheritedMethod = computeSubstituteMethod(otherInheritedMethod, inheritedMethod);
 				if (otherInheritedMethod != null) {
-					if (inheritedMethod.declaringClass != otherInheritedMethod.declaringClass
-						&& isSubstituteParameterSubsignature(inheritedMethod, otherInheritedMethod)) {
+					if (isSubstituteParameterSubsignature(inheritedMethod, otherInheritedMethod)) {
 							if (index == -1)
 								matchingInherited[++index] = inheritedMethod;
 							if (foundMatch[j] == null)
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 25a66de..e1b1872 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Technical University Berlin - extended API and implementation
@@ -12,6 +12,7 @@
 package org.eclipse.jdt.internal.compiler.lookup;
 
 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
+import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
@@ -43,6 +44,7 @@
 		ParameterizedGenericMethodBinding methodSubstitute;
 		TypeVariableBinding[] typeVariables = originalMethod.typeVariables;
 		TypeBinding[] substitutes = invocationSite.genericTypeArguments();
+		InferenceContext inferenceContext = null;
 		TypeBinding[] uncheckedArguments = null;
 //{ObjectTeams: different substitution rules for migrateToTeam()/migrateToBase() methods:
 		MethodBinding migrateMethod = RoleMigrationImplementor.getMigrateMethodSubstitute(originalMethod, arguments, substitutes, scope, invocationSite);
@@ -65,7 +67,7 @@
 			// perform type argument inference (15.12.2.7)
 			// initializes the map of substitutes (var --> type[][]{ equal, extends, super}
 			TypeBinding[] parameters = originalMethod.parameters;
-			InferenceContext inferenceContext = new InferenceContext(originalMethod);
+			inferenceContext = new InferenceContext(originalMethod);
 			methodSubstitute = inferFromArgumentTypes(scope, originalMethod, arguments, parameters, inferenceContext);
 			if (methodSubstitute == null)
 				return null;
@@ -93,10 +95,24 @@
 			}
 		}
 
-		// bounds check
+		/* bounds check: https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159, Inferred types may contain self reference
+		   in formal bounds. If "T extends I<T>" is a original type variable and T was inferred to be I<T> due possibly
+		   to under constraints and resultant glb application per 15.12.2.8, using this.typeArguments to drive the bounds
+		   check against itself is doomed to fail. For, the variable T would after substitution be I<I<T>> and would fail
+		   bounds check against I<T>. Use the inferred types from the context directly - see that there is one round of
+		   extra substitution that has taken place to properly substitute a remaining unresolved variable which also appears
+		   in a formal bound  (So we really have a bounds mismatch between I<I<T>> and I<I<I<T>>>, in the absence of a fix.)
+		*/
+		Substitution substitution = null;
+		if (inferenceContext != null) {
+			substitution = new LingeringTypeVariableEliminator(typeVariables, inferenceContext.substitutes, scope);
+		} else {
+			substitution = methodSubstitute;
+		}
 		for (int i = 0, length = typeVariables.length; i < length; i++) {
 		    TypeVariableBinding typeVariable = typeVariables[i];
-		    TypeBinding substitute = methodSubstitute.typeArguments[i];
+		    TypeBinding substitute = methodSubstitute.typeArguments[i]; // retain for diagnostics
+		    TypeBinding substituteForChecks = Scope.substitute(new LingeringTypeVariableEliminator(typeVariables, null, scope), substitute); // while using this for bounds check
 		    if (uncheckedArguments != null && uncheckedArguments[i] == null) continue; // only bound check if inferred through 15.12.2.6
 //{ObjectTeams: methods with generic declared lifting need to be checked in knowledge of the actual receiver type:
 		    ReferenceBinding actualReceiverRefType = null;
@@ -105,9 +121,9 @@
 		    	if (actualReceiverType instanceof ReferenceBinding)
 		    		actualReceiverRefType = (ReferenceBinding) actualReceiverType;
 		    }
-			switch (typeVariable.boundCheck(methodSubstitute, substitute, actualReceiverRefType)) {
+			switch (typeVariable.boundCheck(substitution, substituteForChecks, actualReceiverRefType)) {
 /* orig:
-			switch (typeVariable.boundCheck(methodSubstitute, substitute)) {
+			switch (typeVariable.boundCheck(substitution, substituteForChecks)) {
   :giro */
 // SH}
 				case TypeConstants.MISMATCH :
@@ -263,12 +279,20 @@
 					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;
+					// https://bugs.eclipse.org/bugs/show_bug.cgi?id=341795 - Per 15.12.2.8, we should fully apply glb
+					if (glb != null) {
+						if (glb.length == 1) {
+							mostSpecificSubstitute = glb[0];
+						} else {
+							TypeBinding [] otherBounds = new TypeBinding[glb.length - 1];
+							System.arraycopy(glb, 1, otherBounds, 0, glb.length - 1);
+							mostSpecificSubstitute = scope.environment().createWildcard(null, 0, glb[0], otherBounds, Wildcard.EXTENDS);
 						}
 					}
+					if (mostSpecificSubstitute != null) {
+						substitutes[i] = mostSpecificSubstitute;
+					}
+				}
 		}
 		return true;
 	}
@@ -451,15 +475,21 @@
     	for (int i = 0; i < varLength; i++) {
     		TypeBinding substitute = inferenceContext.substitutes[i];
     		if (substitute != null) {
-    			this.typeArguments[i] = inferenceContext.substitutes[i];
+    			this.typeArguments[i] = substitute;
     		} else {
     			// remaining unresolved variable are considered to be Object (or their bound actually)
-	    		this.typeArguments[i] = originalVariables[i].upperBound();
+	    		this.typeArguments[i] = inferenceContext.substitutes[i] = originalVariables[i].upperBound();
 	    	}
     	}
-		// may still need an extra substitution at the end (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=121369)
-		// to properly substitute a remaining unresolved variable which also appear in a formal bound
-    	this.typeArguments = Scope.substitute(this, this.typeArguments);
+		/* May still need an extra substitution at the end (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=121369)
+		   to properly substitute a remaining unresolved variable which also appear in a formal bound. See also
+		   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5021635. It is questionable though whether this extra
+		   substitution should take place when the invocation site offers no guidance whatsoever and the type variables
+		   are inferred to be the glb of the published bounds - as there can recursion in the formal bounds, the
+		   inferred bounds would no longer be glb.
+		*/
+		
+		this.typeArguments = Scope.substitute(this, this.typeArguments);
 
     	// adjust method types to reflect latest inference
 		TypeBinding oldReturnType = this.returnType;
@@ -492,6 +522,54 @@
 	    return this;
 	}
 
+	/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=347600 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159
+	   Sometimes due to recursion/circularity in formal bounds, even *published bounds* fail bound check. We need to
+	   break the circularity/self reference in order not to be overly strict during type equivalence checks.  
+	   See also http://bugs.sun.com/view_bug.do?bug_id=6932571
+	 */
+	private static class LingeringTypeVariableEliminator implements Substitution {
+
+		final private TypeVariableBinding [] variables;
+		final private TypeBinding [] substitutes; // when null, substitute type variables by unbounded wildcard
+		final private Scope scope;
+		
+		/**
+		 * @param variables
+		 * @param substitutes when null, substitute type variable by unbounded wildcard
+		 * @param scope
+		 */
+		public LingeringTypeVariableEliminator(TypeVariableBinding [] variables, TypeBinding [] substitutes, Scope scope) {
+			this.variables = variables;
+			this.substitutes = substitutes;
+			this.scope = scope;
+		}
+		// With T mapping to I<T>, answer of I<?>, when given T, having eliminated the circularity/self reference.
+		public TypeBinding substitute(TypeVariableBinding typeVariable) {
+			if (typeVariable.rank >= this.variables.length || this.variables[typeVariable.rank] != typeVariable) {   // not kosher, don't touch.
+				return typeVariable;
+			}
+			if (this.substitutes != null) {
+				return Scope.substitute(new LingeringTypeVariableEliminator(this.variables, null, this.scope), this.substitutes[typeVariable.rank]); 
+			}
+			ReferenceBinding genericType = (ReferenceBinding) (typeVariable.declaringElement instanceof ReferenceBinding ? typeVariable.declaringElement : null);
+			return this.scope.environment().createWildcard(genericType, typeVariable.rank, null, null, Wildcard.UNBOUND);
+		}
+
+		public LookupEnvironment environment() {
+			return this.scope.environment();
+		}
+
+		public boolean isRawSubstitution() {
+			return false;
+		}
+//{ObjectTeams:
+		public ITeamAnchor substituteAnchor(ITeamAnchor anchor, int rank) {
+			// FIXME Auto-generated method stub
+			return null;
+		}
+// SH}
+	}
+
 	/**
 	 * @see org.eclipse.jdt.internal.compiler.lookup.Substitution#isRawSubstitution()
 	 */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
new file mode 100644
index 0000000..c41e93a
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/PolymorphicMethodBinding.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made 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;
+
+/**
+ * Binding denoting a polymorphic method
+ */
+public class PolymorphicMethodBinding extends MethodBinding {
+
+	protected MethodBinding polymorphicMethod;
+
+	public PolymorphicMethodBinding(MethodBinding polymorphicMethod, TypeBinding[] parameterTypes) {
+		super(
+				polymorphicMethod.modifiers,
+				polymorphicMethod.selector,
+				polymorphicMethod.returnType,
+				parameterTypes,
+				polymorphicMethod.thrownExceptions,
+				polymorphicMethod.declaringClass);
+		this.polymorphicMethod = polymorphicMethod;
+		this.tagBits = polymorphicMethod.tagBits;
+	}
+	
+	public PolymorphicMethodBinding(MethodBinding polymorphicMethod, TypeBinding returnType, TypeBinding[] parameterTypes) {
+		super(
+				polymorphicMethod.modifiers,
+				polymorphicMethod.selector,
+				returnType,
+				parameterTypes,
+				polymorphicMethod.thrownExceptions,
+				polymorphicMethod.declaringClass);
+		this.polymorphicMethod = polymorphicMethod;
+		this.tagBits = polymorphicMethod.tagBits;
+	}
+
+	public MethodBinding original() {
+		return this.polymorphicMethod;
+	}
+	
+	public boolean isPolymorphic() {
+		return true;
+	}
+
+	public boolean matches(TypeBinding[] matchingParameters, TypeBinding matchingReturnType) {
+		int cachedParametersLength = this.parameters == null ? 0 : this.parameters.length;
+		int matchingParametersLength = matchingParameters == null ? 0 : matchingParameters.length;
+		if (matchingParametersLength != cachedParametersLength) {
+			return false;
+		}
+		for (int j = 0; j < cachedParametersLength; j++){
+			if (this.parameters[j] != matchingParameters[j]) {
+				return false;
+			}
+		}
+		TypeBinding cachedReturnType = this.returnType;
+		if (matchingReturnType == null) {
+			if (cachedReturnType != null) {
+				return false;
+			}
+		} else if (cachedReturnType == null) {
+			return false;
+		} else if (matchingReturnType != cachedReturnType) {
+			return false;
+		}
+		// all arguments match
+		return true;
+	}
+	
+	/*
+	 * Even if polymorphic methods are varargs method, we don't want them to be treated as varargs method
+	 */
+	public boolean isVarargs() {
+		return false;
+	}
+}
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 8a50ad8..cc3adec 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -28,11 +28,12 @@
 	final int ParameterizedMethodTypeMismatch = 12; // for generic method
 	final int TypeArgumentsForRawGenericMethod = 13; // for generic method
 	final int InvalidTypeForStaticImport = 14;
+	final int InvalidTypeForAutoManagedResource = 15;
 //{ObjectTeams;
-    final int NoTeamContext = 15;
-    final int AnchorNotFinal = 16;
-    final int AnchorNotATeam = 17;
-    final int AnchorNotFound = 18;
-    final int ProblemAlreadyReported = 19;
+    final int NoTeamContext = 20;
+    final int AnchorNotFinal = 21;
+    final int AnchorNotATeam = 22;
+    final int AnchorNotFound = 23;
+    final int ProblemAlreadyReported = 24;
 // SH}
 }
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 c22e4fd..1698cc3 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -600,8 +600,16 @@
 			// remaining types MUST be in java.lang.*
 			switch (typeName[0]) {
 				case 'A' :
-					if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
-						this.id = TypeIds.T_JavaLangAssertionError;
+					switch(typeName.length) {
+						case 13 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_AUTOCLOSEABLE[2]))
+								this.id = TypeIds.T_JavaLangAutoCloseable;
+							return;
+						case 14:
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_ASSERTIONERROR[2]))
+								this.id = TypeIds.T_JavaLangAssertionError;
+							return;
+					}
 					return;
 				case 'B' :
 					switch (typeName.length) {
@@ -717,6 +725,10 @@
 							else if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SYSTEM[2]))
 								this.id = TypeIds.T_JavaLangSystem;
 							return;
+						case 11 :
+							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_SAFEVARARGS[2]))
+								this.id = TypeIds.T_JavaLangSafeVarargs;
+							return;
 						case 12 :
 							if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_STRINGBUFFER[2]))
 								this.id = TypeIds.T_JavaLangStringBuffer;
@@ -745,8 +757,9 @@
 		case 4:
 			if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
 				return;
-			if (!CharOperation.equals(TypeConstants.LANG, this.compoundName[1]))
-				return;
+			packageName = this.compoundName[1];
+			if (packageName.length == 0) return; // just to be safe
+
 			packageName = this.compoundName[2];
 			if (packageName.length == 0) return; // just to be safe
 			typeName = this.compoundName[3];
@@ -790,6 +803,17 @@
 						}
 					}
 					return;
+				case 'i':
+					if (CharOperation.equals(packageName, TypeConstants.INVOKE)) {
+						if (typeName.length == 0) return; // just to be safe
+						switch (typeName[0]) {
+							case 'M' :
+								if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE[3]))
+									this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
+								return;
+						}
+					}
+					return;
 				case 'r' :
 					if (CharOperation.equals(packageName, TypeConstants.REFLECT)) {
 						switch (typeName[0]) {
@@ -810,6 +834,34 @@
 					return;
 			}
 			break;
+		case 5 :
+			if (!CharOperation.equals(TypeConstants.JAVA, this.compoundName[0]))
+				return;
+			packageName = this.compoundName[1];
+			if (packageName.length == 0) return; // just to be safe
+
+			if (CharOperation.equals(TypeConstants.LANG, packageName)) {
+				packageName = this.compoundName[2];
+				if (packageName.length == 0) return; // just to be safe
+				switch (packageName[0]) {
+					case 'i' :
+						if (CharOperation.equals(packageName, TypeConstants.INVOKE)) { 
+							typeName = this.compoundName[3];
+							if (typeName.length == 0) return; // just to be safe
+							switch (typeName[0]) {
+								case 'M' :
+									char[] memberTypeName = this.compoundName[4];
+									if (memberTypeName.length == 0) return; // just to be safe
+									if (CharOperation.equals(typeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[3])
+											&& CharOperation.equals(memberTypeName, TypeConstants.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE[4]))
+										this.id = TypeIds.T_JavaLangInvokeMethodHandlePolymorphicSignature;
+									return;
+							}
+						}
+						return;
+				}
+				return;
+			}
 	}
 }
 
@@ -1684,7 +1736,7 @@
 }
 
 public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
-	SimpleLookupTable store = storedAnnotations(false);
+	SimpleLookupTable store = storedAnnotations(forceInitialization);
 	return store == null ? null : (AnnotationHolder) store.get(binding);
 }
 
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 504fad1..424f751 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
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 import org.eclipse.jdt.internal.compiler.util.ObjectVector;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.compiler.util.SimpleSet;
 import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
 import org.eclipse.objectteams.otdt.internal.core.compiler.ast.TypeAnchorReference;
@@ -34,6 +35,7 @@
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.AnchorMapping;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.CallinCalloutScope;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.DependentTypeBinding;
+import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.ITeamAnchor;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.OTClassScope;
 import org.eclipse.objectteams.otdt.internal.core.compiler.lookup.RoleTypeBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
@@ -371,7 +373,7 @@
 			}
 		}
 		if (removed == 0) return result;
-		if (length == removed) return null;
+		if (length == removed) return null; // how is this possible ???
 		TypeBinding[] trimmedResult = new TypeBinding[length - removed];
 		for (int i = 0, index = 0; i < length; i++) {
 			TypeBinding iType = result[i];
@@ -475,6 +477,24 @@
 			        TypeBinding[] originalOtherBounds = wildcard.otherBounds;
 			        TypeBinding[] substitutedOtherBounds = substitute(substitution, originalOtherBounds);
 			        if (substitutedBound != originalBound || originalOtherBounds != substitutedOtherBounds) {
+			        	if (originalOtherBounds != null) {
+			        		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=347145: the constituent intersecting types have changed
+			        		   in the last round of substitution. Reevaluate the composite intersection type, as there is a possibility
+			        		   of the intersection collapsing into one of the constituents, the other being fully subsumed.
+			        		*/
+			    			TypeBinding [] bounds = new TypeBinding[1 + substitutedOtherBounds.length];
+			    			bounds[0] = substitutedBound;
+			    			System.arraycopy(substitutedOtherBounds, 0, bounds, 1, substitutedOtherBounds.length);
+			    			TypeBinding[] glb = Scope.greaterLowerBound(bounds); // re-evaluate
+			    			if (glb != null && glb != bounds) {
+			    				substitutedBound = glb[0];
+		    					if (glb.length == 1) {
+			    					substitutedOtherBounds = null;
+			    				} else {
+			    					System.arraycopy(glb, 1, substitutedOtherBounds = new TypeBinding[glb.length - 1], 0, glb.length - 1);
+			    				}
+			    			}
+			        	}
 		        		return wildcard.environment.createWildcard(wildcard.genericType, wildcard.rank, substitutedBound, substitutedOtherBounds, wildcard.boundKind);
 			        }
 		        }
@@ -625,8 +645,13 @@
 			}
 		}
 
-		if (parameterCompatibilityLevel(method, arguments) > NOT_COMPATIBLE)
+		if (parameterCompatibilityLevel(method, arguments) > NOT_COMPATIBLE) {
+			if ((method.tagBits & TagBits.AnnotationPolymorphicSignature) != 0) {
+				// generate polymorphic method
+				return this.environment().createPolymorphicMethod(method, arguments);
+			}
 			return method;
+		}
 		if (genericTypeArguments != null)
 			return new ProblemMethodBinding(method, method.selector, arguments, ProblemReasons.ParameterizedMethodTypeMismatch);
 		return null; // incompatible
@@ -4522,4 +4547,148 @@
 	int startIndex() {
 		return 0;
 	}
+	/* Given an allocation type and arguments at the allocation site, answer a synthetic generic static factory method
+	   that could instead be invoked with identical results. Return null if no compatible, visible, most specific method
+	   could be found. This method is modeled after Scope.getConstructor and Scope.getMethod.
+	 */
+	public MethodBinding getStaticFactory (ReferenceBinding allocationType, ReferenceBinding originalEnclosingType, TypeBinding[] argumentTypes, final InvocationSite allocationSite) {
+		TypeVariableBinding[] classTypeVariables = allocationType.typeVariables();
+		int classTypeVariablesArity = classTypeVariables.length;
+		MethodBinding[] methods = allocationType.getMethods(TypeConstants.INIT, argumentTypes.length);
+		MethodBinding [] staticFactories = new MethodBinding[methods.length];
+		int sfi = 0;
+		for (int i = 0, length = methods.length; i < length; i++) {
+			MethodBinding method = methods[i];
+			int paramLength = method.parameters.length;
+			boolean isVarArgs = method.isVarargs();
+			if (argumentTypes.length != paramLength)
+				if (!isVarArgs || argumentTypes.length < paramLength - 1)
+					continue; // incompatible
+			TypeVariableBinding[] methodTypeVariables = method.typeVariables();
+			int methodTypeVariablesArity = methodTypeVariables.length;
+	        
+			MethodBinding staticFactory = new MethodBinding(method.modifiers | ClassFileConstants.AccStatic, TypeConstants.SYNTHETIC_STATIC_FACTORY,
+																		null, null, null, method.declaringClass);
+			staticFactory.typeVariables = new TypeVariableBinding[classTypeVariablesArity + methodTypeVariablesArity];
+			final SimpleLookupTable map = new SimpleLookupTable(classTypeVariablesArity + methodTypeVariablesArity);
+			// Rename each type variable T of the type to T'
+			final LookupEnvironment environment = environment();
+			for (int j = 0; j < classTypeVariablesArity; j++) {
+				map.put(classTypeVariables[j], staticFactory.typeVariables[j] = new TypeVariableBinding(CharOperation.concat(classTypeVariables[j].sourceName, "'".toCharArray()), //$NON-NLS-1$
+																			staticFactory, j, environment));
+			}
+			// Rename each type variable U of method U to U''.
+			for (int j = classTypeVariablesArity, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) {
+				map.put(methodTypeVariables[j - classTypeVariablesArity], 
+						(staticFactory.typeVariables[j] = new TypeVariableBinding(CharOperation.concat(methodTypeVariables[j - classTypeVariablesArity].sourceName, "''".toCharArray()), //$NON-NLS-1$
+																			staticFactory, j, environment)));
+			}
+			ReferenceBinding enclosingType = originalEnclosingType;
+			while (enclosingType != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=345968
+				if (enclosingType.kind() == Binding.PARAMETERIZED_TYPE) {
+					final ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) enclosingType;
+					final ReferenceBinding genericType = parameterizedType.genericType();
+					TypeVariableBinding[] enclosingClassTypeVariables = genericType.typeVariables();
+					int enclosingClassTypeVariablesArity = enclosingClassTypeVariables.length;
+					for (int j = 0; j < enclosingClassTypeVariablesArity; j++) {
+						map.put(enclosingClassTypeVariables[j], parameterizedType.arguments[j]);
+					}
+				}
+				enclosingType = enclosingType.enclosingType();
+			}
+			final Scope scope = this;
+			Substitution substitution = new Substitution() {
+					public LookupEnvironment environment() {
+						return scope.environment();
+					}
+					public boolean isRawSubstitution() {
+						return false;
+					}
+					public TypeBinding substitute(TypeVariableBinding typeVariable) {
+						TypeBinding retVal = (TypeBinding) map.get(typeVariable);
+						return retVal != null ? retVal : typeVariable;
+					}
+//{ObjectTeams:
+					public ITeamAnchor substituteAnchor(ITeamAnchor anchor, int rank) {
+						// FIXME Auto-generated method stub
+						return null;
+					}
+// SH}
+				};
+
+			// initialize new variable bounds
+			for (int j = 0, max = classTypeVariablesArity + methodTypeVariablesArity; j < max; j++) {
+				TypeVariableBinding originalVariable = j < classTypeVariablesArity ? classTypeVariables[j] : methodTypeVariables[j - classTypeVariablesArity];
+				TypeBinding substitutedType = (TypeBinding) map.get(originalVariable);
+				if (substitutedType instanceof TypeVariableBinding) {
+					TypeVariableBinding substitutedVariable = (TypeVariableBinding) substitutedType;
+					TypeBinding substitutedSuperclass = Scope.substitute(substitution, originalVariable.superclass);
+					ReferenceBinding[] substitutedInterfaces = Scope.substitute(substitution, originalVariable.superInterfaces);
+					if (originalVariable.firstBound != null) {
+						substitutedVariable.firstBound = originalVariable.firstBound == originalVariable.superclass
+								? substitutedSuperclass // could be array type or interface
+										: substitutedInterfaces[0];
+					}
+					switch (substitutedSuperclass.kind()) {
+						case Binding.ARRAY_TYPE :
+							substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+							substitutedVariable.superInterfaces = substitutedInterfaces;
+							break;
+						default:
+							if (substitutedSuperclass.isInterface()) {
+								substitutedVariable.superclass = environment.getResolvedType(TypeConstants.JAVA_LANG_OBJECT, null);
+								int interfaceCount = substitutedInterfaces.length;
+								System.arraycopy(substitutedInterfaces, 0, substitutedInterfaces = new ReferenceBinding[interfaceCount+1], 1, interfaceCount);
+								substitutedInterfaces[0] = (ReferenceBinding) substitutedSuperclass;
+								substitutedVariable.superInterfaces = substitutedInterfaces;
+							} else {
+								substitutedVariable.superclass = (ReferenceBinding) substitutedSuperclass; // typeVar was extending other typeVar which got substituted with interface
+								substitutedVariable.superInterfaces = substitutedInterfaces;
+							}
+					}
+				}
+			}
+		    TypeVariableBinding[] returnTypeParameters = new TypeVariableBinding[classTypeVariablesArity];
+			for (int j = 0; j < classTypeVariablesArity; j++) {
+				returnTypeParameters[j] = (TypeVariableBinding) map.get(classTypeVariables[j]);
+			}
+			staticFactory.returnType = environment.createParameterizedType(allocationType, returnTypeParameters, allocationType.enclosingType());
+			staticFactory.parameters = Scope.substitute(substitution, method.parameters);
+			staticFactory.thrownExceptions = Scope.substitute(substitution, method.thrownExceptions);
+			if (staticFactory.thrownExceptions == null) { 
+				staticFactory.thrownExceptions = Binding.NO_EXCEPTIONS;
+			}
+			staticFactories[sfi++] = new ParameterizedMethodBinding((ParameterizedTypeBinding) environment.convertToParameterizedType(staticFactory.declaringClass),
+																												staticFactory);
+		}
+		if (sfi == 0)
+			return null;
+		if (sfi != methods.length) {
+			System.arraycopy(staticFactories, 0, staticFactories = new MethodBinding[sfi], 0, sfi);
+		}
+		MethodBinding[] compatible = new MethodBinding[sfi];
+		int compatibleIndex = 0;
+		for (int i = 0; i < sfi; i++) {
+			MethodBinding compatibleMethod = computeCompatibleMethod(staticFactories[i], argumentTypes, allocationSite);
+			if (compatibleMethod != null) {
+				if (compatibleMethod.isValidBinding())
+					compatible[compatibleIndex++] = compatibleMethod;
+			}
+		}
+
+		if (compatibleIndex == 0) {
+			return null;
+		}
+		MethodBinding[] visible = new MethodBinding[compatibleIndex];
+		int visibleIndex = 0;
+		for (int i = 0; i < compatibleIndex; i++) {
+			MethodBinding method = compatible[i];
+			if (method.canBeSeenBy(allocationSite, this))
+				visible[visibleIndex++] = method;
+		}
+		if (visibleIndex == 0) {
+			return null;
+		}
+		return visibleIndex == 1 ? visible[0] : mostSpecificMethodBinding(visible, visibleIndex, argumentTypes, allocationSite, allocationType);
+	}
 }
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 e204350..dba34ce 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
@@ -2133,6 +2133,21 @@
 		}
 	}
 
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=337799
+	if (this.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_7) {
+		if ((method.tagBits & TagBits.AnnotationSafeVarargs) != 0) {
+			if (!method.isVarargs()) {
+				methodDecl.scope.problemReporter().safeVarargsOnFixedArityMethod(method);
+			} else if (!method.isStatic() && !method.isFinal() && !method.isConstructor()) {
+				methodDecl.scope.problemReporter().safeVarargsOnNonFinalInstanceMethod(method);
+			}
+		} else if (method.parameters != null && method.parameters.length > 0 && method.isVarargs()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=337795
+			if (!method.parameters[method.parameters.length - 1].isReifiable()) {
+				methodDecl.scope.problemReporter().possibleHeapPollutionFromVararg(methodDecl.arguments[methodDecl.arguments.length - 1]);
+			}
+		}
+	}
+
 	boolean foundReturnTypeProblem = false;
 	if (!method.isConstructor()) {
 		TypeReference returnType = methodDecl instanceof MethodDeclaration
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 6352d2a..ad67306 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
@@ -4,7 +4,7 @@
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -59,6 +59,11 @@
 
 	long IsArgument = ASTNode.Bit11; // local
 	long ClearPrivateModifier = ASTNode.Bit10; // constructor binding
+	
+	// for java 7
+	long IsEffectivelyFinal = ASTNode.Bit12; // local
+	long MultiCatchParameter = ASTNode.Bit13; // local
+	long IsResource = ASTNode.Bit14; // local
 
 	// test bits to see if parts of binary types are faulted
 	long AreFieldsSorted = ASTNode.Bit13;
@@ -124,19 +129,32 @@
 	long AnnotationInherited = ASTNode.Bit49L;
 	long AnnotationOverride = ASTNode.Bit50L;
 	long AnnotationSuppressWarnings = ASTNode.Bit51L;
+	/** @since 3.7 - java 7 safe vargs invocation */
+	long AnnotationSafeVarargs = ASTNode.Bit52L;
+	/** @since 3.7 - java 7 MethodHandle.invokeExact(..)/invokeGeneric(..)*/
+	long AnnotationPolymorphicSignature = ASTNode.Bit53L;
+
 //{ObjectTeams: one more standard annotation:
 	long AnnotationInstantiation = ASTNode.Bit21;
 // SH}
-	long AllStandardAnnotationsMask = AnnotationTargetMASK | AnnotationRetentionMASK | AnnotationDeprecated | AnnotationDocumented | AnnotationInherited |  AnnotationOverride | AnnotationSuppressWarnings
-//{ObjectTeams: one more standard annotation:
-										| AnnotationInstantiation
-// SH}
-	;
 
-	long DefaultValueResolved = ASTNode.Bit52L;
+	long AllStandardAnnotationsMask = AnnotationTargetMASK
+				| AnnotationRetentionMASK
+				| AnnotationDeprecated
+				| AnnotationDocumented
+				| AnnotationInherited
+				| AnnotationOverride
+				| AnnotationSuppressWarnings
+//{ObjectTeams: one more standard annotation:
+				| AnnotationInstantiation
+// SH}
+				| AnnotationSafeVarargs
+				| AnnotationPolymorphicSignature;
+
+	long DefaultValueResolved = ASTNode.Bit54L;
 
 	// set when type contains non-private constructor(s)
-	long HasNonPrivateConstructor = ASTNode.Bit53L;
+	long HasNonPrivateConstructor = ASTNode.Bit55L;
 
 //{ObjectTeams:
 	// is parameterized type instantiated via tsuper-link?
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 6e1a1a4..b45fb89 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,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -598,12 +598,11 @@
 	return true;
 }
 
-private boolean isProvableDistinctSubType(TypeBinding otherType, boolean isClassLiteral) {
+private boolean isProvableDistinctSubType(TypeBinding otherType) {
 	if (otherType.isInterface()) {
 		if (isInterface())
 			return false;
 		if (isArrayType()
-			//	|| isClassLiteral // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322531
 				|| ((this instanceof ReferenceBinding) && ((ReferenceBinding) this).isFinal())
 				|| (isTypeVariable() && ((TypeVariableBinding)this).superclass().isFinal())) {
 			return !isCompatibleWith(otherType);
@@ -612,7 +611,6 @@
 	} else {
 		if (isInterface()) {
 			if (otherType.isArrayType()
-				//	|| isClassLiteral // https://bugs.eclipse.org/bugs/show_bug.cgi?id=322531
 					|| ((otherType instanceof ReferenceBinding) && ((ReferenceBinding) otherType).isFinal())
 					|| (otherType.isTypeVariable() && ((TypeVariableBinding)otherType).superclass().isFinal())) {
 				return !isCompatibleWith(otherType);
@@ -897,10 +895,10 @@
 		if (lowerBound2 != null) {
 			return !lowerBound2.isCompatibleWith(upperBound1);
 		} else if (upperBound2 != null) {
-			return upperBound1.isProvableDistinctSubType(upperBound2, false)
-							&& upperBound2.isProvableDistinctSubType(upperBound1, false);
+			return upperBound1.isProvableDistinctSubType(upperBound2)
+							&& upperBound2.isProvableDistinctSubType(upperBound1);
 		} else {
-			return otherArgument.isProvableDistinctSubType(upperBound1, genericType.id == TypeIds.T_JavaLangClass);
+			return otherArgument.isProvableDistinctSubType(upperBound1);
 		}
 	} else {
 		if (lowerBound2 != null) {
@@ -909,7 +907,7 @@
 			}
 			return !lowerBound2.isCompatibleWith(this);
 		} else if (upperBound2 != null) {
-			return isProvableDistinctSubType(upperBound2, genericType.id == TypeIds.T_JavaLangClass);
+			return isProvableDistinctSubType(upperBound2);
 		} else {
 			return true; // ground types should have been the same
 		}
@@ -972,6 +970,36 @@
 // SH}
 		return true;
 	switch (otherType.kind()) {
+	// handle captured wildcards.
+		case Binding.TYPE_PARAMETER: {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=347426
+			if (!isParameterizedType() || !otherType.isCapture()) {
+				return false;
+			}
+			CaptureBinding capture = (CaptureBinding) otherType;
+			WildcardBinding wildcard = capture.wildcard;
+			TypeBinding upperBound = null;
+			TypeBinding [] otherBounds = null;
+			switch (wildcard.boundKind) {
+				case Wildcard.SUPER:
+					return false; // T super syntax isn't allowed, impossible capture.
+				case Wildcard.UNBOUND:
+					TypeVariableBinding variable = wildcard.genericType.typeVariables()[wildcard.rank];
+					upperBound = variable.upperBound();
+					otherBounds = variable.boundsCount() > 1 ? variable.otherUpperBounds() : null;
+					break;
+				case Wildcard.EXTENDS:
+					upperBound = wildcard.bound;
+					otherBounds = wildcard.otherBounds;
+					break;
+			}
+			// Given class A<T extends B<?>>, A<?> cannot be the universe of all parameterizations of A
+			if (upperBound.id == TypeIds.T_JavaLangObject && otherBounds == null) {
+				return false; // but given class A<T>, A<?> stays an unbounded wildcard, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=348956
+			}
+			otherType = capture.environment.createWildcard(null, 0, upperBound, otherBounds, Wildcard.EXTENDS);
+			return isTypeArgumentContainedBy(otherType);
+		}
 		// allow wildcard containment
 		case Binding.WILDCARD_TYPE:
 		case Binding.INTERSECTION_TYPE:
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 e3ef49d..e75db5c 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
@@ -4,7 +4,7 @@
  * are made 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
  *******************************************************************************/
@@ -134,11 +134,27 @@
 			"CORBA".toCharArray(), //$NON-NLS-1$
 			"Stub".toCharArray(), //$NON-NLS-1$
 	};
+	char[][] JAVA_LANG_SAFEVARARGS =  {JAVA, LANG, "SafeVarargs".toCharArray()}; //$NON-NLS-1$
+	char[] INVOKE = "invoke".toCharArray(); //$NON-NLS-1$
+	char[][] JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE = { // Signature while parsing binary file
+			JAVA,
+			LANG,
+			INVOKE,
+			"MethodHandle".toCharArray(), //$NON-NLS-1$
+			"PolymorphicSignature".toCharArray() //$NON-NLS-1$
+	};
+	char[][] JAVA_LANG_INVOKE_METHODHANDLE_$_POLYMORPHICSIGNATURE = { // Signature while parsing source file
+			JAVA,
+			LANG,
+			INVOKE,
+			"MethodHandle$PolymorphicSignature".toCharArray() //$NON-NLS-1$
+	};
+	char[][] JAVA_LANG_AUTOCLOSEABLE =  {JAVA, LANG, "AutoCloseable".toCharArray()}; //$NON-NLS-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
+	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;
@@ -156,6 +172,7 @@
 	char[] SYNTHETIC_ENCLOSING_INSTANCE_PREFIX = "this$".toCharArray(); //$NON-NLS-1$
 	char[] SYNTHETIC_ACCESS_METHOD_PREFIX =  "access$".toCharArray(); //$NON-NLS-1$
 	char[] SYNTHETIC_ENUM_CONSTANT_INITIALIZATION_METHOD_PREFIX =  " enum constant initialization$".toCharArray(); //$NON-NLS-1$
+	char[] SYNTHETIC_STATIC_FACTORY =  "<factory>".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 b6f685d..74b3d88 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
@@ -4,7 +4,7 @@
  * are made 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
  *******************************************************************************/
@@ -88,6 +88,14 @@
 	final int T_JavaIoException = 58;
 	
 	final int T_JavaUtilCollection = 59;
+	
+	// java 7
+	final int T_JavaLangSafeVarargs = 60;
+	
+	final int T_JavaLangInvokeMethodHandlePolymorphicSignature = 61;
+
+	// java 7 java.lang.AutoCloseable
+	final int T_JavaLangAutoCloseable = 62;
 
 	final int NoId = Integer.MAX_VALUE;
 
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 1c85762..d11f88d 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, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made 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
  *     Fraunhofer FIRST - extended API and implementation
@@ -71,6 +71,11 @@
 	public final boolean isFinal() {
 		return (this.modifiers & ClassFileConstants.AccFinal) != 0;
 	}
+	
+	public final boolean isEffectivelyFinal() {
+		return (this.tagBits & TagBits.IsEffectivelyFinal) != 0;
+	}
+	
 	public char[] readableName() {
 //{ObjectTeams: pretty printing for generated names:
 	if (CharOperation.prefixEquals(IOTConstants.OT_DOLLAR_NAME, this.name))
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 31a7f88..091f126 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
@@ -4,8 +4,7 @@
  * are made 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
- * $Id: Parser.java 23404 2010-02-03 14:10:22Z stephan $
- *
+ * 
  * 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
@@ -1248,6 +1247,7 @@
 				length);
 		}
 		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
 
 		//the default constructor with the correct number of argument
 		//will be created and added by the TC (see createsInternalConstructorWithBinding)
@@ -1260,6 +1260,7 @@
 		anonymousTypeDeclaration.bodyEnd = this.endStatementPosition;
 		if (anonymousTypeDeclaration.allocation != null) {
 			anonymousTypeDeclaration.allocation.sourceEnd = this.endStatementPosition;
+			checkForDiamond(anonymousTypeDeclaration.allocation.type);
 		}
 		if (length == 0 && !containsComment(anonymousTypeDeclaration.bodyStart, anonymousTypeDeclaration.bodyEnd)) {
 			anonymousTypeDeclaration.bits |= ASTNode.UndocumentedEmptyBlock;
@@ -1268,6 +1269,30 @@
 		this.astLengthPtr--;
 	}
 }
+protected void checkForDiamond(TypeReference allocType) {
+	if (allocType instanceof ParameterizedSingleTypeReference) {
+		ParameterizedSingleTypeReference type = (ParameterizedSingleTypeReference) allocType;
+		if (type.typeArguments == TypeReference.NO_TYPE_ARGUMENTS) {
+			if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+				problemReporter().diamondNotBelow17(allocType);
+			}
+			if (this.options.sourceLevel > ClassFileConstants.JDK1_4) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=351965
+				type.bits |= ASTNode.IsDiamond;
+			} // else don't even bother to recognize this as <>
+		}
+	} 
+	else if (allocType instanceof ParameterizedQualifiedTypeReference) {
+		ParameterizedQualifiedTypeReference type = (ParameterizedQualifiedTypeReference) allocType;
+		if (type.typeArguments[type.typeArguments.length - 1] == TypeReference.NO_TYPE_ARGUMENTS) { // Don't care for X<>.Y<> and X<>.Y<String>
+			if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+				problemReporter().diamondNotBelow17(allocType, type.typeArguments.length - 1);
+			}
+			if (this.options.sourceLevel > ClassFileConstants.JDK1_4) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=351965
+				type.bits |= ASTNode.IsDiamond;
+			} // else don't even bother to recognize this as <>
+		}
+	}
+}
 protected ParameterizedQualifiedTypeReference computeQualifiedGenericsFromRightSide(TypeReference rightSide, int dim) {
 	int nameSize = this.identifierLengthStack[this.identifierLengthPtr];
 	int tokensSize = nameSize;
@@ -2886,6 +2911,43 @@
 	// Catches ::= Catches CatchClause
 	optimizedConcatNodeLists();
 }
+protected void consumeCatchFormalParameter() {
+	// CatchFormalParameter ::= Modifiersopt CatchType VariableDeclaratorId
+	this.identifierLengthPtr--;
+	char[] identifierName = this.identifierStack[this.identifierPtr];
+	long namePositions = this.identifierPositionStack[this.identifierPtr--];
+	int extendedDimensions = this.intStack[this.intPtr--]; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=348369
+	TypeReference type = (TypeReference) this.astStack[this.astPtr--];
+	if (extendedDimensions > 0) {
+		type = type.copyDims(type.dimensions() + extendedDimensions);
+		type.sourceEnd = this.endPosition;
+	}
+	this.astLengthPtr--;
+	int modifierPositions = this.intStack[this.intPtr--];
+	this.intPtr--;
+	Argument arg =
+		new Argument(
+			identifierName,
+			namePositions,
+			type,
+			this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
+	arg.bits &= ~ASTNode.IsArgument;
+	arg.declarationSourceStart = modifierPositions;
+	// consume annotations
+	int length;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		System.arraycopy(
+			this.expressionStack,
+			(this.expressionPtr -= length) + 1,
+			arg.annotations = new Annotation[length],
+			0,
+			length);
+	}
+	pushOnAstStack(arg);
+	/* if incomplete method header, this.listLength counter will not have been reset,
+		indicating that some arguments are available on the stack */
+	this.listLength++;
+}
 protected void consumeCatchHeader() {
 	// CatchDeclaration ::= 'catch' '(' FormalParameter ')' '{'
 
@@ -2915,6 +2977,27 @@
 	this.restartRecovery = true; // request to restart from here on
 	this.lastIgnoredToken = -1;
 }
+protected void consumeCatchType() {
+	// CatchType ::= UnionType
+	int length = this.astLengthStack[this.astLengthPtr--];
+	if (length != 1) {
+		TypeReference[] typeReferences;
+		System.arraycopy(
+				this.astStack,
+				(this.astPtr -= length) + 1,
+				(typeReferences = new TypeReference[length]),
+				0,
+				length);
+		UnionTypeReference typeReference = new UnionTypeReference(typeReferences);
+		pushOnAstStack(typeReference);
+		if (this.options.sourceLevel < ClassFileConstants.JDK1_7) {
+			problemReporter().multiCatchNotBelow17(typeReference);
+		}
+	} else {
+		// push back the type reference
+		pushOnAstLengthStack(1);
+	}
+}
 protected void consumeClassBodyDeclaration() {
 	// ClassBodyDeclaration ::= Diet NestedMethod CreateInitializer Block
 	//push an Initializer
@@ -3254,7 +3337,7 @@
 				length);
 		}
 		alloc.type = getTypeReference(0);
-
+		checkForDiamond(alloc.type);
 		length = this.genericsLengthStack[this.genericsLengthPtr--];
 		this.genericsPtr -= length;
 		System.arraycopy(this.genericsStack, this.genericsPtr + 1, alloc.typeArguments = new TypeReference[length], 0, length);
@@ -3283,6 +3366,7 @@
 			this.genericsPtr -= length;
 			System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
 			allocationExpression.sourceStart = this.intStack[this.intPtr--];
+			checkForDiamond(allocationExpression.type);
 		}
 	}
 	
@@ -3318,6 +3402,7 @@
 				length);
 		}
 		alloc.type = getTypeReference(0);
+		checkForDiamond(alloc.type);
 
 		length = this.genericsLengthStack[this.genericsLengthPtr--];
 		this.genericsPtr -= length;
@@ -3347,6 +3432,7 @@
 			this.genericsPtr -= length;
 			System.arraycopy(this.genericsStack, this.genericsPtr + 1, allocationExpression.typeArguments = new TypeReference[length], 0, length);
 			allocationExpression.sourceStart = this.intStack[this.intPtr--];
+			checkForDiamond(allocationExpression.type);
 		}
 	}
 }
@@ -3683,6 +3769,15 @@
 	// DimWithOrWithOutExprs ::= DimWithOrWithOutExprs DimWithOrWithOutExpr
 	concatExpressionLists();
 }
+protected void consumeUnionType() {
+	// UnionType ::= UnionType '|' Type
+	pushOnAstStack(getTypeReference(this.intStack[this.intPtr--]));
+	optimizedConcatNodeLists();
+}
+protected void consumeUnionTypeAsClassType() {
+	// UnionType ::= Type
+	pushOnAstStack(getTypeReference(this.intStack[this.intPtr--]));
+}
 protected void consumeEmptyAnnotationTypeMemberDeclarationsopt() {
 	// AnnotationTypeMemberDeclarationsopt ::= $empty
 	pushOnAstLengthStack(0);
@@ -4646,6 +4741,7 @@
 	this.expressionLengthPtr--;
 	Expression expression = this.expressionStack[this.expressionPtr--];
 	expression.statementEnd = this.endStatementPosition;
+	expression.bits |= ASTNode.InsideExpressionStatement;
 	pushOnAstStack(expression);
 }
 protected void consumeFieldAccess(boolean isSuperAccess) {
@@ -4658,14 +4754,14 @@
 			this.identifierPositionStack[this.identifierPtr--]);
 	this.identifierLengthPtr--;
 	if (isSuperAccess) {
-		//considerates the fieldReference beginning at the 'super' ....
+		//considers the fieldReference beginning at the 'super' ....
 		fr.sourceStart = this.intStack[this.intPtr--];
 		fr.receiver = new SuperReference(fr.sourceStart, this.endPosition);
 		pushOnExpressionStack(fr);
 	} else {
 		//optimize push/pop
 		fr.receiver = this.expressionStack[this.expressionPtr];
-		//fieldreference begins at the receiver
+		//field reference begins at the receiver
 		fr.sourceStart = fr.receiver.sourceStart;
 		this.expressionStack[this.expressionPtr] = fr;
 	}
@@ -4839,84 +4935,6 @@
 		}
 	}
 }
-protected void consumeCatchFormalParameter(boolean isVarArgs) {
-	// FormalParameter ::= Type VariableDeclaratorId ==> false
-	// FormalParameter ::= Modifiers Type VariableDeclaratorId ==> true
-	/*
-	this.astStack :
-	this.identifierStack : type identifier
-	this.intStack : dim dim
-	 ==>
-	this.astStack : Argument
-	this.identifierStack :
-	this.intStack :
-	*/
-
-	this.identifierLengthPtr--;
-	char[] identifierName = this.identifierStack[this.identifierPtr];
-	long namePositions = this.identifierPositionStack[this.identifierPtr--];
-	int extendedDimensions = this.intStack[this.intPtr--];
-	int endOfEllipsis = 0;
-	if (isVarArgs) {
-		endOfEllipsis = this.intStack[this.intPtr--];
-	}
-	int firstDimensions = this.intStack[this.intPtr--];
-	final int typeDimensions = firstDimensions + extendedDimensions;
-//{ObjectTeams: LiftingTypeRefernce is introduced here as specific type reference
-/*	orig:
-	TypeReference type = getTypeReference(typeDimensions);
-  :giro */
-	TypeReference type = null;
-
-	if (this.astPtr > -1 && this.astStack[this.astPtr] instanceof LiftingTypeReference)
-		type = completeLiftingTypeReference(typeDimensions);
-	else
-		type = getTypeReference(typeDimensions);
-// Markus Witte}
-	if (isVarArgs) {
-		type = copyDims(type, typeDimensions + 1);
-		if (extendedDimensions == 0) {
-			type.sourceEnd = endOfEllipsis;
-		}
-		type.bits |= ASTNode.IsVarArgs; // set isVarArgs
-	}
-	int modifierPositions = this.intStack[this.intPtr--];
-	this.intPtr--;
-	Argument arg =
-		new Argument(
-			identifierName,
-			namePositions,
-			type,
-			this.intStack[this.intPtr + 1] & ~ClassFileConstants.AccDeprecated); // modifiers
-	arg.bits &= ~ASTNode.IsArgument;
-	arg.declarationSourceStart = modifierPositions;
-	// consume annotations
-	int length;
-	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
-		System.arraycopy(
-			this.expressionStack,
-			(this.expressionPtr -= length) + 1,
-			arg.annotations = new Annotation[length],
-			0,
-			length);
-	}
-	pushOnAstStack(arg);
-
-	/* if incomplete method header, this.listLength counter will not have been reset,
-		indicating that some arguments are available on the stack */
-	this.listLength++;
-
-	if(isVarArgs) {
-		if (!this.statementRecoveryActivated &&
-				this.options.sourceLevel < ClassFileConstants.JDK1_5 &&
-				this.lastErrorEndPositionBeforeRecovery < this.scanner.currentPosition) {
-				problemReporter().invalidUsageOfVarargs(arg);
-		} else if (!this.statementRecoveryActivated &&
-				extendedDimensions > 0) {
-			problemReporter().illegalExtendedDimensions(arg);
-		}
-	}
-}
 protected void consumeFormalParameterList() {
 	// FormalParameterList ::= FormalParameterList ',' FormalParameter
 	optimizedConcatNodeLists();
@@ -4926,16 +4944,24 @@
 	pushOnAstLengthStack(0);
 }
 protected void consumeGenericType() {
+	// GenericType ::= ClassOrInterface TypeArguments
 	// nothing to do
-	// Will be consume by a getTypeRefence call
+	// Will be consume by a getTypeReference call
 }
 protected void consumeGenericTypeArrayType() {
 	// nothing to do
-	// Will be consume by a getTypeRefence call
+	// Will be consume by a getTypeReference call
 }
 protected void consumeGenericTypeNameArrayType() {
 	// nothing to do
-	// Will be consume by a getTypeRefence call
+	// Will be consume by a getTypeReference call
+}
+protected void consumeGenericTypeWithDiamond() {
+	// GenericType ::= ClassOrInterface '<' '>'
+	// zero type arguments == <>
+	pushOnGenericsLengthStack(-1);
+	concatGenericsLists();
+	this.intPtr--;	// pop the null dimension pushed in by consumeReferenceType, as we have no type between <>, getTypeReference won't kick in 
 }
 protected void consumeImportDeclaration() {
 	// SingleTypeImportDeclaration ::= SingleTypeImportDeclarationName ';'
@@ -6160,6 +6186,10 @@
 protected void consumeModifiers2() {
 	this.expressionLengthStack[this.expressionLengthPtr - 1] += this.expressionLengthStack[this.expressionLengthPtr--];
 }
+protected void consumeMultipleResources() {
+	// Resources ::= Resources ';' Resource
+	concatNodeLists();
+}
 protected void consumeNameArrayType() {
 	pushOnGenericsLengthStack(0); // handle type arguments
 	pushOnGenericsIdentifiersLengthStack(this.identifierLengthStack[this.identifierLengthPtr]);
@@ -6926,6 +6956,21 @@
 protected void consumeReferenceType3() {
 	pushOnGenericsStack(getTypeReference(this.intStack[this.intPtr--]));
 }
+protected void consumeResourceAsLocalVariableDeclaration() {
+	// Resource ::= Type PushModifiers VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+	// Resource ::= Modifiers Type PushRealModifiers VariableDeclaratorId EnterVariable '=' ForceNoDiet VariableInitializer RestoreDiet ExitVariableWithInitialization
+	consumeLocalVariableDeclaration();
+}
+protected void consumeResourceSpecification() {
+	// ResourceSpecification ::= '(' Resources ')'
+}
+protected void consumeResourceOptionalTrailingSemiColon(boolean punctuated) {
+	// TrailingSemiColon ::= ';'
+	LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
+	if (punctuated) {
+		localDeclaration.declarationSourceEnd = this.endStatementPosition;
+	}
+}
 //{ObjectTeams: intended side effect
 private void consumeRestoreBaseKeyword() {
     // restoring the interpretation of maybe-keyword 'base'.
@@ -6950,2076 +6995,2128 @@
 			break;
  
     case 52 : if (DEBUG) { System.out.println("ReferenceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
-		    consumeReferenceType();   
+		    consumeReferenceType();  
 			break;
  
     case 56 : if (DEBUG) { System.out.println("ClassOrInterface ::= Name"); }  //$NON-NLS-1$
-		    consumeClassOrInterfaceName();   
+		    consumeClassOrInterfaceName();  
 			break;
  
     case 57 : if (DEBUG) { System.out.println("ClassOrInterface ::= GenericType DOT Name"); }  //$NON-NLS-1$
-		    consumeClassOrInterface();   
+		    consumeClassOrInterface();  
 			break;
  
     case 58 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface TypeArguments"); }  //$NON-NLS-1$
-		    consumeGenericType();   
+		    consumeGenericType();  
 			break;
  
-    case 59 : if (DEBUG) { System.out.println("LiftingType ::= ClassType as ClassType"); }  //$NON-NLS-1$
+    case 59 : if (DEBUG) { System.out.println("GenericType ::= ClassOrInterface LESS GREATER"); }  //$NON-NLS-1$
+		    consumeGenericTypeWithDiamond();  
+			break;
+ 
+    case 60 : if (DEBUG) { System.out.println("LiftingType ::= ClassType as ClassType"); }  //$NON-NLS-1$
 		    consumeLiftingType();  
 			break;
  
-    case 60 : if (DEBUG) { System.out.println("ArrayLiftingType ::= ArrayType as ArrayType"); }  //$NON-NLS-1$
+    case 61 : if (DEBUG) { System.out.println("ArrayLiftingType ::= ArrayType as ArrayType"); }  //$NON-NLS-1$
 		    consumeLiftingTypeArray();  
 			break;
  
-    case 61 : if (DEBUG) { System.out.println("InvalidDeclaredArrayLifting ::= ClassType as ArrayType"); }  //$NON-NLS-1$
+    case 62 : if (DEBUG) { System.out.println("InvalidDeclaredArrayLifting ::= ClassType as ArrayType"); }  //$NON-NLS-1$
 		    consumeLiftingTypeArrayInvalid();  
 			break;
  
-    case 62 : if (DEBUG) { System.out.println("InvalidDeclaredArrayLifting ::= ArrayType as ClassType"); }  //$NON-NLS-1$
+    case 63 : if (DEBUG) { System.out.println("InvalidDeclaredArrayLifting ::= ArrayType as ClassType"); }  //$NON-NLS-1$
 		    consumeLiftingTypeArrayInvalid();  
 			break;
  
-    case 63 : if (DEBUG) { System.out.println("BaseAnchoredType ::= base DOT SimpleName"); }  //$NON-NLS-1$
+    case 64 : if (DEBUG) { System.out.println("BaseAnchoredType ::= base DOT SimpleName"); }  //$NON-NLS-1$
 		    consumeBaseAnchoredType();  
 			break;
  
-    case 66 : if (DEBUG) { System.out.println("ArrayTypeWithTypeArgumentsName ::= GenericType DOT Name"); }  //$NON-NLS-1$
-		    consumeArrayTypeWithTypeArgumentsName();   
+    case 67 : if (DEBUG) { System.out.println("ArrayTypeWithTypeArgumentsName ::= GenericType DOT Name"); }  //$NON-NLS-1$
+		    consumeArrayTypeWithTypeArgumentsName();  
 			break;
  
-    case 67 : if (DEBUG) { System.out.println("ArrayType ::= PrimitiveType Dims"); }  //$NON-NLS-1$
-		    consumePrimitiveArrayType();   
+    case 68 : if (DEBUG) { System.out.println("ArrayType ::= PrimitiveType Dims"); }  //$NON-NLS-1$
+		    consumePrimitiveArrayType();  
 			break;
  
-    case 68 : if (DEBUG) { System.out.println("ArrayType ::= Name Dims"); }  //$NON-NLS-1$
-		    consumeNameArrayType();   
+    case 69 : if (DEBUG) { System.out.println("ArrayType ::= Name Dims"); }  //$NON-NLS-1$
+		    consumeNameArrayType();  
 			break;
  
-    case 69 : if (DEBUG) { System.out.println("ArrayType ::= ArrayTypeWithTypeArgumentsName Dims"); }  //$NON-NLS-1$
-		    consumeGenericTypeNameArrayType();   
+    case 70 : if (DEBUG) { System.out.println("ArrayType ::= ArrayTypeWithTypeArgumentsName Dims"); }  //$NON-NLS-1$
+		    consumeGenericTypeNameArrayType();  
 			break;
  
-    case 70 : if (DEBUG) { System.out.println("ArrayType ::= GenericType Dims"); }  //$NON-NLS-1$
-		    consumeGenericTypeArrayType();   
+    case 71 : if (DEBUG) { System.out.println("ArrayType ::= GenericType Dims"); }  //$NON-NLS-1$
+		    consumeGenericTypeArrayType();  
 			break;
  
-    case 75 : if (DEBUG) { System.out.println("QualifiedName ::= Name DOT SimpleName"); }  //$NON-NLS-1$
+    case 76 : if (DEBUG) { System.out.println("QualifiedName ::= Name DOT SimpleName"); }  //$NON-NLS-1$
 		    consumeQualifiedName();  
 			break;
  
-    case 76 : if (DEBUG) { System.out.println("CompilationUnit ::= EnterCompilationUnit..."); }  //$NON-NLS-1$
+    case 77 : if (DEBUG) { System.out.println("CompilationUnit ::= EnterCompilationUnit..."); }  //$NON-NLS-1$
 		    consumeCompilationUnit();  
 			break;
  
-    case 77 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration"); }  //$NON-NLS-1$
-		    consumeInternalCompilationUnit();  
-			break;
- 
-    case 78 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
+    case 78 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration"); }  //$NON-NLS-1$
 		    consumeInternalCompilationUnit();  
 			break;
  
     case 79 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
-		    consumeInternalCompilationUnitWithTypes();  
+		    consumeInternalCompilationUnit();  
 			break;
  
     case 80 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
 		    consumeInternalCompilationUnitWithTypes();  
 			break;
  
-    case 81 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); }  //$NON-NLS-1$
+    case 81 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= PackageDeclaration..."); }  //$NON-NLS-1$
+		    consumeInternalCompilationUnitWithTypes();  
+			break;
+ 
+    case 82 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); }  //$NON-NLS-1$
 		    consumeInternalCompilationUnit();  
 			break;
  
-    case 82 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= TypeDeclarations"); }  //$NON-NLS-1$
+    case 83 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= TypeDeclarations"); }  //$NON-NLS-1$
 		    consumeInternalCompilationUnitWithTypes();  
 			break;
  
-    case 83 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); }  //$NON-NLS-1$
+    case 84 : if (DEBUG) { System.out.println("InternalCompilationUnit ::= ImportDeclarations..."); }  //$NON-NLS-1$
 		    consumeInternalCompilationUnitWithTypes();  
 			break;
  
-    case 84 : if (DEBUG) { System.out.println("InternalCompilationUnit ::="); }  //$NON-NLS-1$
+    case 85 : if (DEBUG) { System.out.println("InternalCompilationUnit ::="); }  //$NON-NLS-1$
 		    consumeEmptyInternalCompilationUnit();  
 			break;
  
-    case 85 : if (DEBUG) { System.out.println("ReduceImports ::="); }  //$NON-NLS-1$
+    case 86 : if (DEBUG) { System.out.println("ReduceImports ::="); }  //$NON-NLS-1$
 		    consumeReduceImports();  
 			break;
  
-    case 86 : if (DEBUG) { System.out.println("EnterCompilationUnit ::="); }  //$NON-NLS-1$
+    case 87 : if (DEBUG) { System.out.println("EnterCompilationUnit ::="); }  //$NON-NLS-1$
 		    consumeEnterCompilationUnit();  
 			break;
  
-    case 104 : if (DEBUG) { System.out.println("CatchHeader ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
+    case 105 : if (DEBUG) { System.out.println("CatchHeader ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
 		    consumeCatchHeader();  
 			break;
  
-    case 105 : if (DEBUG) { System.out.println("CatchFormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
-		    consumeCatchFormalParameter(false);  
-			break;
- 
-    case 106 : if (DEBUG) { System.out.println("CatchFormalParameter ::= Modifiersopt Type ELLIPSIS..."); }  //$NON-NLS-1$
-		    consumeCatchFormalParameter(true);  
-			break;
- 
-    case 108 : if (DEBUG) { System.out.println("ImportDeclarations ::= ImportDeclarations..."); }  //$NON-NLS-1$
+    case 107 : if (DEBUG) { System.out.println("ImportDeclarations ::= ImportDeclarations..."); }  //$NON-NLS-1$
 		    consumeImportDeclarations();  
 			break;
  
-    case 110 : if (DEBUG) { System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); }  //$NON-NLS-1$
+    case 109 : if (DEBUG) { System.out.println("TypeDeclarations ::= TypeDeclarations TypeDeclaration"); }  //$NON-NLS-1$
 		    consumeTypeDeclarations();  
 			break;
  
-    case 111 : if (DEBUG) { System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); }  //$NON-NLS-1$
-		     consumePackageDeclaration();  
+    case 110 : if (DEBUG) { System.out.println("PackageDeclaration ::= PackageDeclarationName SEMICOLON"); }  //$NON-NLS-1$
+		    consumePackageDeclaration();  
 			break;
  
-    case 112 : if (DEBUG) { System.out.println("PackageDeclarationName ::= Modifiers package..."); }  //$NON-NLS-1$
-		     consumePackageDeclarationNameWithModifiers();  
+    case 111 : if (DEBUG) { System.out.println("PackageDeclarationName ::= Modifiers package..."); }  //$NON-NLS-1$
+		    consumePackageDeclarationNameWithModifiers();  
 			break;
  
-    case 113 : if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name"); }  //$NON-NLS-1$
-		     consumePackageDeclarationName();  
+    case 112 : if (DEBUG) { System.out.println("PackageDeclarationName ::= PackageComment package Name"); }  //$NON-NLS-1$
+		    consumePackageDeclarationName();  
 			break;
  
-    case 114 : if (DEBUG) { System.out.println("PackageComment ::="); }  //$NON-NLS-1$
-		     consumePackageComment();  
+    case 113 : if (DEBUG) { System.out.println("PackageComment ::="); }  //$NON-NLS-1$
+		    consumePackageComment();  
 			break;
  
-    case 120 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); }  //$NON-NLS-1$
+    case 119 : if (DEBUG) { System.out.println("SingleTypeImportDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 121 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import ImportName"); }  //$NON-NLS-1$
+    case 120 : if (DEBUG) { System.out.println("SingleTypeImportDeclarationName ::= import ImportName"); }  //$NON-NLS-1$
 		    consumeSingleTypeImportDeclarationName();  
 			break;
  
-    case 123 : if (DEBUG) { System.out.println("ImportName ::= Name DOT team DOT Name"); }  //$NON-NLS-1$
+    case 122 : if (DEBUG) { System.out.println("ImportName ::= Name DOT team DOT Name"); }  //$NON-NLS-1$
 		    consumeNameContainingTeam();  
 			break;
  
-    case 124 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
+    case 123 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 125 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); }  //$NON-NLS-1$
+    case 124 : if (DEBUG) { System.out.println("TypeImportOnDemandDeclarationName ::= import Name DOT..."); }  //$NON-NLS-1$
 		    consumeTypeImportOnDemandDeclarationName();  
 			break;
  
-     case 128 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+     case 127 : if (DEBUG) { System.out.println("TypeDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyTypeDeclaration();  
 			break;
  
-    case 132 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); }  //$NON-NLS-1$
+    case 131 : if (DEBUG) { System.out.println("Modifiers ::= Modifiers Modifier"); }  //$NON-NLS-1$
 		    consumeModifiers2();  
 			break;
  
-    case 144 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); }  //$NON-NLS-1$
+    case 143 : if (DEBUG) { System.out.println("Modifier ::= Annotation"); }  //$NON-NLS-1$
 		    consumeAnnotationAsModifier();  
 			break;
  
-    case 148 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); }  //$NON-NLS-1$
+    case 147 : if (DEBUG) { System.out.println("ClassDeclaration ::= ClassHeader ClassBody"); }  //$NON-NLS-1$
 		    consumeClassDeclaration();  
 			break;
  
-    case 149 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); }  //$NON-NLS-1$
+    case 148 : if (DEBUG) { System.out.println("ClassHeader ::= ClassHeaderName ClassHeaderExtendsopt..."); }  //$NON-NLS-1$
 		    consumeClassHeader();  
 			break;
  
-    case 150 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); }  //$NON-NLS-1$
+    case 149 : if (DEBUG) { System.out.println("ClassHeaderName ::= ClassHeaderName1 TypeParameters"); }  //$NON-NLS-1$
 		    consumeTypeHeaderNameWithTypeParameters();  
 			break;
  
-    case 152 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); }  //$NON-NLS-1$
+    case 151 : if (DEBUG) { System.out.println("ClassHeaderName1 ::= Modifiersopt class Identifier"); }  //$NON-NLS-1$
 		    consumeClassHeaderName1();  
 			break;
  
-    case 153 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); }  //$NON-NLS-1$
+    case 152 : if (DEBUG) { System.out.println("ClassHeaderExtends ::= extends ClassType"); }  //$NON-NLS-1$
 		    consumeClassHeaderExtends();  
 			break;
  
-    case 154 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); }  //$NON-NLS-1$
+    case 153 : if (DEBUG) { System.out.println("ClassHeaderImplements ::= implements InterfaceTypeList"); }  //$NON-NLS-1$
 		    consumeClassHeaderImplements();  
 			break;
  
-    case 157 : if (DEBUG) { System.out.println("ClassHeaderPlayedBy ::= playedBy ClassType"); }  //$NON-NLS-1$
+    case 156 : if (DEBUG) { System.out.println("ClassHeaderPlayedBy ::= playedBy ClassType"); }  //$NON-NLS-1$
 		    consumeClassHeaderPlayedBy();  
 			break;
  
-    case 163 : if (DEBUG) { System.out.println("PredicateHeader ::= when"); }  //$NON-NLS-1$
+    case 162 : if (DEBUG) { System.out.println("PredicateHeader ::= when"); }  //$NON-NLS-1$
 		    consumePredicate(false);  
 			break;
  
-    case 165 : if (DEBUG) { System.out.println("BasePredicateHeader ::= base when"); }  //$NON-NLS-1$
+    case 164 : if (DEBUG) { System.out.println("BasePredicateHeader ::= base when"); }  //$NON-NLS-1$
 		    consumePredicate(true);  
 			break;
  
-    case 166 : if (DEBUG) { System.out.println("PredicateBody ::= LPAREN ForceNoDiet Expression..."); }  //$NON-NLS-1$
+    case 165 : if (DEBUG) { System.out.println("PredicateBody ::= LPAREN ForceNoDiet Expression..."); }  //$NON-NLS-1$
 		    consumePredicateExpression();  
 			break;
  
-    case 167 : if (DEBUG) { System.out.println("PredicateBody ::= LPAREN RPAREN"); }  //$NON-NLS-1$
+    case 166 : if (DEBUG) { System.out.println("PredicateBody ::= LPAREN RPAREN"); }  //$NON-NLS-1$
 		    consumePredicateMissingExpression();  
 			break;
  
-    case 168 : if (DEBUG) { System.out.println("ForceBaseIsIdentifier ::="); }  //$NON-NLS-1$
+    case 167 : if (DEBUG) { System.out.println("ForceBaseIsIdentifier ::="); }  //$NON-NLS-1$
 		    consumeForceBaseIsIdentifier();  
 			break;
  
-    case 169 : if (DEBUG) { System.out.println("RestoreBaseKeyword ::="); }  //$NON-NLS-1$
+    case 168 : if (DEBUG) { System.out.println("RestoreBaseKeyword ::="); }  //$NON-NLS-1$
 		    consumeRestoreBaseKeyword();  
 			break;
  
-    case 171 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); }  //$NON-NLS-1$
+    case 170 : if (DEBUG) { System.out.println("InterfaceTypeList ::= InterfaceTypeList COMMA..."); }  //$NON-NLS-1$
 		    consumeInterfaceTypeList();  
 			break;
  
-    case 172 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
+    case 171 : if (DEBUG) { System.out.println("InterfaceType ::= ClassOrInterfaceType"); }  //$NON-NLS-1$
 		    consumeInterfaceType();  
 			break;
  
-    case 175 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); }  //$NON-NLS-1$
+    case 174 : if (DEBUG) { System.out.println("ClassBodyDeclarations ::= ClassBodyDeclarations..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclarations();  
 			break;
  
-    case 179 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod..."); }  //$NON-NLS-1$
+    case 178 : if (DEBUG) { System.out.println("ClassBodyDeclaration ::= Diet NestedMethod..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclaration();  
 			break;
  
-    case 180 : if (DEBUG) { System.out.println("Diet ::="); }  //$NON-NLS-1$
+    case 179 : if (DEBUG) { System.out.println("Diet ::="); }  //$NON-NLS-1$
 		    consumeDiet();  
 			break;
 
-    case 181 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod CreateInitializer..."); }  //$NON-NLS-1$
+    case 180 : if (DEBUG) { System.out.println("Initializer ::= Diet NestedMethod CreateInitializer..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclaration();  
 			break;
  
-    case 182 : if (DEBUG) { System.out.println("CreateInitializer ::="); }  //$NON-NLS-1$
+    case 181 : if (DEBUG) { System.out.println("CreateInitializer ::="); }  //$NON-NLS-1$
 		    consumeCreateInitializer();  
 			break;
 
-    case 191 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 190 : if (DEBUG) { System.out.println("ClassMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyTypeDeclaration();  
 			break;
 
-    case 194 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 193 : if (DEBUG) { System.out.println("FieldDeclaration ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeFieldDeclaration();  
 			break;
  
-    case 196 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); }  //$NON-NLS-1$
+    case 195 : if (DEBUG) { System.out.println("VariableDeclarators ::= VariableDeclarators COMMA..."); }  //$NON-NLS-1$
 		    consumeVariableDeclarators();  
 			break;
  
-    case 199 : if (DEBUG) { System.out.println("EnterVariable ::="); }  //$NON-NLS-1$
+    case 198 : if (DEBUG) { System.out.println("EnterVariable ::="); }  //$NON-NLS-1$
 		    consumeEnterVariable();  
 			break;
  
-    case 200 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); }  //$NON-NLS-1$
+    case 199 : if (DEBUG) { System.out.println("ExitVariableWithInitialization ::="); }  //$NON-NLS-1$
 		    consumeExitVariableWithInitialization();  
 			break;
  
-    case 201 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); }  //$NON-NLS-1$
+    case 200 : if (DEBUG) { System.out.println("ExitVariableWithoutInitialization ::="); }  //$NON-NLS-1$
 		    consumeExitVariableWithoutInitialization();  
 			break;
  
-    case 202 : if (DEBUG) { System.out.println("ForceNoDiet ::="); }  //$NON-NLS-1$
+    case 201 : if (DEBUG) { System.out.println("ForceNoDiet ::="); }  //$NON-NLS-1$
 		    consumeForceNoDiet();  
 			break;
  
-    case 203 : if (DEBUG) { System.out.println("RestoreDiet ::="); }  //$NON-NLS-1$
+    case 202 : if (DEBUG) { System.out.println("RestoreDiet ::="); }  //$NON-NLS-1$
 		    consumeRestoreDiet();  
 			break;
  
-    case 208 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
+    case 207 : if (DEBUG) { System.out.println("MethodDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
 		    // set to true to consume a method with a body
-  consumeMethodDeclaration(true);   
+ consumeMethodDeclaration(true);  
 			break;
  
-    case 209 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); }  //$NON-NLS-1$
+    case 208 : if (DEBUG) { System.out.println("AbstractMethodDeclaration ::= MethodHeader SEMICOLON"); }  //$NON-NLS-1$
 		    // set to false to consume a method without body
-  consumeMethodDeclaration(false);  
+ consumeMethodDeclaration(false);  
 			break;
  
-    case 210 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); }  //$NON-NLS-1$
+    case 209 : if (DEBUG) { System.out.println("MethodHeader ::= MethodHeaderName FormalParameterListopt"); }  //$NON-NLS-1$
 		    consumeMethodHeader();  
 			break;
  
-    case 211 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); }  //$NON-NLS-1$
+    case 210 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt TypeParameters Type..."); }  //$NON-NLS-1$
 		    consumeMethodHeaderNameWithTypeParameters(false);  
 			break;
  
-    case 212 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); }  //$NON-NLS-1$
+    case 211 : if (DEBUG) { System.out.println("MethodHeaderName ::= Modifiersopt Type Identifier LPAREN"); }  //$NON-NLS-1$
 		    consumeMethodHeaderName(false);  
 			break;
  
-    case 213 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); }  //$NON-NLS-1$
+    case 212 : if (DEBUG) { System.out.println("MethodHeaderRightParen ::= RPAREN"); }  //$NON-NLS-1$
 		    consumeMethodHeaderRightParen();  
 			break;
  
-    case 214 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); }  //$NON-NLS-1$
+    case 213 : if (DEBUG) { System.out.println("MethodHeaderExtendedDims ::= Dimsopt"); }  //$NON-NLS-1$
 		    consumeMethodHeaderExtendedDims();  
 			break;
  
-    case 215 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); }  //$NON-NLS-1$
+    case 214 : if (DEBUG) { System.out.println("MethodHeaderThrowsClause ::= throws ClassTypeList"); }  //$NON-NLS-1$
 		    consumeMethodHeaderThrowsClause();  
 			break;
  
-    case 216 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
+    case 215 : if (DEBUG) { System.out.println("ConstructorHeader ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
 		    consumeConstructorHeader();  
 			break;
  
-    case 217 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); }  //$NON-NLS-1$
+    case 216 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt TypeParameters..."); }  //$NON-NLS-1$
 		    consumeConstructorHeaderNameWithTypeParameters();  
 			break;
  
-    case 218 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); }  //$NON-NLS-1$
+    case 217 : if (DEBUG) { System.out.println("ConstructorHeaderName ::= Modifiersopt Identifier LPAREN"); }  //$NON-NLS-1$
 		    consumeConstructorHeaderName();  
 			break;
  
-    case 220 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); }  //$NON-NLS-1$
+    case 219 : if (DEBUG) { System.out.println("FormalParameterList ::= FormalParameterList COMMA..."); }  //$NON-NLS-1$
 		    consumeFormalParameterList();  
 			break;
  
-    case 221 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 220 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeFormalParameter(false);  
 			break;
  
-    case 222 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS..."); }  //$NON-NLS-1$
+    case 221 : if (DEBUG) { System.out.println("FormalParameter ::= Modifiersopt Type ELLIPSIS..."); }  //$NON-NLS-1$
 		    consumeFormalParameter(true);  
 			break;
  
-    case 224 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); }  //$NON-NLS-1$
+    case 222 : if (DEBUG) { System.out.println("CatchFormalParameter ::= Modifiersopt CatchType..."); }  //$NON-NLS-1$
+		    consumeCatchFormalParameter();  
+			break;
+ 
+    case 223 : if (DEBUG) { System.out.println("CatchType ::= UnionType"); }  //$NON-NLS-1$
+		    consumeCatchType();  
+			break;
+ 
+    case 224 : if (DEBUG) { System.out.println("UnionType ::= Type"); }  //$NON-NLS-1$
+		    consumeUnionTypeAsClassType();  
+			break;
+ 
+    case 225 : if (DEBUG) { System.out.println("UnionType ::= UnionType OR Type"); }  //$NON-NLS-1$
+		    consumeUnionType();  
+			break;
+ 
+    case 227 : if (DEBUG) { System.out.println("ClassTypeList ::= ClassTypeList COMMA ClassTypeElt"); }  //$NON-NLS-1$
 		    consumeClassTypeList();  
 			break;
  
-    case 225 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); }  //$NON-NLS-1$
+    case 228 : if (DEBUG) { System.out.println("ClassTypeElt ::= ClassType"); }  //$NON-NLS-1$
 		    consumeClassTypeElt();  
 			break;
  
-    case 226 : if (DEBUG) { System.out.println("MethodBody ::= Predicateopt NestedMethod LBRACE..."); }  //$NON-NLS-1$
+    case 229 : if (DEBUG) { System.out.println("MethodBody ::= Predicateopt NestedMethod LBRACE..."); }  //$NON-NLS-1$
 		    consumeMethodBody();  
 			break;
  
-    case 227 : if (DEBUG) { System.out.println("NestedMethod ::="); }  //$NON-NLS-1$
+    case 230 : if (DEBUG) { System.out.println("NestedMethod ::="); }  //$NON-NLS-1$
 		    consumeNestedMethod();  
 			break;
  
-    case 231 : if (DEBUG) { System.out.println("CalloutBinding ::= CalloutHeaderLong..."); }  //$NON-NLS-1$
+    case 234 : if (DEBUG) { System.out.println("CalloutBinding ::= CalloutHeaderLong..."); }  //$NON-NLS-1$
 		    consumeCalloutBindingLong();  
 			break;
  
-    case 232 : if (DEBUG) { System.out.println("CalloutHeaderLong ::= CalloutBindingLeftLong..."); }  //$NON-NLS-1$
+    case 235 : if (DEBUG) { System.out.println("CalloutHeaderLong ::= CalloutBindingLeftLong..."); }  //$NON-NLS-1$
 		    consumeCalloutHeader();  
 			break;
  
-    case 233 : if (DEBUG) { System.out.println("CalloutHeaderLong ::= CalloutBindingLeftLong..."); }  //$NON-NLS-1$
+    case 236 : if (DEBUG) { System.out.println("CalloutHeaderLong ::= CalloutBindingLeftLong..."); }  //$NON-NLS-1$
 		    consumeCalloutHeader();  
 			break;
  
-    case 234 : if (DEBUG) { System.out.println("CalloutBindingLeftLong ::= MethodSpecLong CalloutKind"); }  //$NON-NLS-1$
+    case 237 : if (DEBUG) { System.out.println("CalloutBindingLeftLong ::= MethodSpecLong CalloutKind"); }  //$NON-NLS-1$
 		    consumeCalloutBindingLeft(true);  
 			break;
  
-    case 235 : if (DEBUG) { System.out.println("CalloutBinding ::= Modifiersopt CalloutBindingLeftShort"); }  //$NON-NLS-1$
+    case 238 : if (DEBUG) { System.out.println("CalloutBinding ::= Modifiersopt CalloutBindingLeftShort"); }  //$NON-NLS-1$
 		    consumeCalloutHeader();  
 			break;
  
-    case 236 : if (DEBUG) { System.out.println("CalloutBindingLeftShort ::= MethodSpecShort CalloutKind"); }  //$NON-NLS-1$
+    case 239 : if (DEBUG) { System.out.println("CalloutBindingLeftShort ::= MethodSpecShort CalloutKind"); }  //$NON-NLS-1$
 		    consumeCalloutBindingLeft(false);  
 			break;
  
-    case 237 : if (DEBUG) { System.out.println("CalloutBinding ::= Modifiersopt CalloutBindingLeftShort"); }  //$NON-NLS-1$
+    case 240 : if (DEBUG) { System.out.println("CalloutBinding ::= Modifiersopt CalloutBindingLeftShort"); }  //$NON-NLS-1$
 		    consumeCalloutParameterMappingsInvalid();  
 			break;
  
-    case 242 : if (DEBUG) { System.out.println("CalloutModifier ::= get"); }  //$NON-NLS-1$
+    case 245 : if (DEBUG) { System.out.println("CalloutModifier ::= get"); }  //$NON-NLS-1$
 		    consumeCalloutModifier(TokenNameget);  
 			break;
  
-    case 243 : if (DEBUG) { System.out.println("CalloutModifier ::= set"); }  //$NON-NLS-1$
+    case 246 : if (DEBUG) { System.out.println("CalloutModifier ::= set"); }  //$NON-NLS-1$
 		    consumeCalloutModifier(TokenNameset);  
 			break;
  
-    case 245 : if (DEBUG) { System.out.println("CalloutParameterMappingsopt ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 248 : if (DEBUG) { System.out.println("CalloutParameterMappingsopt ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeParameterMappingsEmpty();  
 			break;
  
-    case 249 : if (DEBUG) { System.out.println("CalloutParameterMappingList ::=..."); }  //$NON-NLS-1$
+    case 252 : if (DEBUG) { System.out.println("CalloutParameterMappingList ::=..."); }  //$NON-NLS-1$
 		    consumeParameterMappingList();  
 			break;
  
-    case 250 : if (DEBUG) { System.out.println("ParameterMapping ::= Expression BINDOUT Identifier"); }  //$NON-NLS-1$
+    case 253 : if (DEBUG) { System.out.println("ParameterMapping ::= Expression BINDOUT Identifier"); }  //$NON-NLS-1$
 		    consumeParameterMappingOut();  
 			break;
  
-    case 251 : if (DEBUG) { System.out.println("ParameterMapping ::= Identifier BINDIN..."); }  //$NON-NLS-1$
+    case 254 : if (DEBUG) { System.out.println("ParameterMapping ::= Identifier BINDIN..."); }  //$NON-NLS-1$
 		    consumeParameterMappingIn();  
 			break;
  
-    case 252 : if (DEBUG) { System.out.println("NestedParamMappings ::="); }  //$NON-NLS-1$
+    case 255 : if (DEBUG) { System.out.println("NestedParamMappings ::="); }  //$NON-NLS-1$
 		    consumeNestedParamMappings();  
 			break;
  
-    case 253 : if (DEBUG) { System.out.println("CallinBinding ::= CallinHeaderLong..."); }  //$NON-NLS-1$
+    case 256 : if (DEBUG) { System.out.println("CallinBinding ::= CallinHeaderLong..."); }  //$NON-NLS-1$
 		    consumeCallinBindingLong();  
 			break;
  
-    case 254 : if (DEBUG) { System.out.println("CallinHeaderLong ::= CallinBindingLeftLong..."); }  //$NON-NLS-1$
+    case 257 : if (DEBUG) { System.out.println("CallinHeaderLong ::= CallinBindingLeftLong..."); }  //$NON-NLS-1$
 		    consumeCallinHeader();  
 			break;
  
-    case 255 : if (DEBUG) { System.out.println("CallinHeaderLong ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
+    case 258 : if (DEBUG) { System.out.println("CallinHeaderLong ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
 		    consumeCallinHeader();  
 			break;
  
-    case 256 : if (DEBUG) { System.out.println("CallinBindingLeftLong ::= MethodSpecLong BINDIN"); }  //$NON-NLS-1$
+    case 259 : if (DEBUG) { System.out.println("CallinBindingLeftLong ::= MethodSpecLong BINDIN"); }  //$NON-NLS-1$
 		    consumeCallinBindingLeft(true);  
 			break;
  
-    case 257 : if (DEBUG) { System.out.println("CallinBinding ::= Modifiersopt CallinBindingLeftShort..."); }  //$NON-NLS-1$
+    case 260 : if (DEBUG) { System.out.println("CallinBinding ::= Modifiersopt CallinBindingLeftShort..."); }  //$NON-NLS-1$
 		    consumeCallinHeader();  
 			break;
  
-    case 258 : if (DEBUG) { System.out.println("CallinBinding ::= Modifiersopt CallinLabel Modifiersopt"); }  //$NON-NLS-1$
+    case 261 : if (DEBUG) { System.out.println("CallinBinding ::= Modifiersopt CallinLabel Modifiersopt"); }  //$NON-NLS-1$
 		    consumeCallinHeader();  
 			break;
  
-    case 259 : if (DEBUG) { System.out.println("CallinBindingLeftShort ::= MethodSpecShort BINDIN"); }  //$NON-NLS-1$
+    case 262 : if (DEBUG) { System.out.println("CallinBindingLeftShort ::= MethodSpecShort BINDIN"); }  //$NON-NLS-1$
 		    consumeCallinBindingLeft(false);  
 			break;
  
-    case 260 : if (DEBUG) { System.out.println("CallinLabel ::= SimpleName COLON"); }  //$NON-NLS-1$
+    case 263 : if (DEBUG) { System.out.println("CallinLabel ::= SimpleName COLON"); }  //$NON-NLS-1$
 		    consumeCallinLabel();  
 			break;
  
-    case 261 : if (DEBUG) { System.out.println("CallinModifier ::= replace"); }  //$NON-NLS-1$
+    case 264 : if (DEBUG) { System.out.println("CallinModifier ::= replace"); }  //$NON-NLS-1$
 		    consumeCallinModifier(TokenNamereplace);  
 			break;
  
-    case 262 : if (DEBUG) { System.out.println("CallinModifier ::= before"); }  //$NON-NLS-1$
+    case 265 : if (DEBUG) { System.out.println("CallinModifier ::= before"); }  //$NON-NLS-1$
 		    consumeCallinModifier(TokenNamebefore);  
 			break;
  
-    case 263 : if (DEBUG) { System.out.println("CallinModifier ::= after"); }  //$NON-NLS-1$
+    case 266 : if (DEBUG) { System.out.println("CallinModifier ::= after"); }  //$NON-NLS-1$
 		    consumeCallinModifier(TokenNameafter);  
 			break;
  
-    case 264 : if (DEBUG) { System.out.println("InvalidCallinModifier ::="); }  //$NON-NLS-1$
+    case 267 : if (DEBUG) { System.out.println("InvalidCallinModifier ::="); }  //$NON-NLS-1$
 		    consumeCallinModifierMissing();  
 			break;
  
-    case 265 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt..."); }  //$NON-NLS-1$
+    case 268 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt..."); }  //$NON-NLS-1$
 		    consumeCallinBindingInvalid(false,false);  
 			break;
  
-    case 266 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
+    case 269 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
 		    consumeCallinBindingInvalid(false,false);  
 			break;
  
-    case 267 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt..."); }  //$NON-NLS-1$
+    case 270 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt..."); }  //$NON-NLS-1$
 		    consumeCallinBindingInvalid(false,true);  
 			break;
  
-    case 268 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
+    case 271 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
 		    consumeCallinBindingInvalid(false,true);  
 			break;
  
-    case 269 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= CallinBindingLeftLong..."); }  //$NON-NLS-1$
+    case 272 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= CallinBindingLeftLong..."); }  //$NON-NLS-1$
 		    consumeCallinBindingInvalid(true,false);  
 			break;
  
-    case 270 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
+    case 273 : if (DEBUG) { System.out.println("InvalidCallinBinding ::= Modifiersopt CallinLabel..."); }  //$NON-NLS-1$
 		    consumeCallinBindingInvalid(true,false);  
 			break;
  
-    case 272 : if (DEBUG) { System.out.println("CallinParameterMappingsopt ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 275 : if (DEBUG) { System.out.println("CallinParameterMappingsopt ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeParameterMappingsEmpty();  
 			break;
  
-    case 276 : if (DEBUG) { System.out.println("CallinParameterMappingList ::=..."); }  //$NON-NLS-1$
+    case 279 : if (DEBUG) { System.out.println("CallinParameterMappingList ::=..."); }  //$NON-NLS-1$
 		    consumeParameterMappingList();  
 			break;
  
-    case 277 : if (DEBUG) { System.out.println("MethodSpecShort ::= SimpleName"); }  //$NON-NLS-1$
+    case 280 : if (DEBUG) { System.out.println("MethodSpecShort ::= SimpleName"); }  //$NON-NLS-1$
 		    consumeMethodSpecShort();  
 			break;
  
-    case 278 : if (DEBUG) { System.out.println("MethodSpecLong ::= MethodHeaderName..."); }  //$NON-NLS-1$
+    case 281 : if (DEBUG) { System.out.println("MethodSpecLong ::= MethodHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodSpecLong(false);  
 			break;
  
-    case 279 : if (DEBUG) { System.out.println("MethodSpecLong ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
+    case 282 : if (DEBUG) { System.out.println("MethodSpecLong ::= ConstructorHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodSpecLongCtor();  
 			break;
  
-    case 280 : if (DEBUG) { System.out.println("BaseMethodSpecLong ::= MethodHeaderName..."); }  //$NON-NLS-1$
+    case 283 : if (DEBUG) { System.out.println("BaseMethodSpecLong ::= MethodHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodSpecLong(false);  
 			break;
  
-    case 281 : if (DEBUG) { System.out.println("BaseMethodSpecLong ::= MethodSpecNamePlus..."); }  //$NON-NLS-1$
+    case 284 : if (DEBUG) { System.out.println("BaseMethodSpecLong ::= MethodSpecNamePlus..."); }  //$NON-NLS-1$
 		    consumeMethodSpecLong(true);  
 			break;
  
-    case 282 : if (DEBUG) { System.out.println("MethodSpecNamePlus ::= Modifiersopt Type PLUS Identifier"); }  //$NON-NLS-1$
+    case 285 : if (DEBUG) { System.out.println("MethodSpecNamePlus ::= Modifiersopt Type PLUS Identifier"); }  //$NON-NLS-1$
 		    consumeMethodHeaderName(false);  
 			break;
  
-    case 283 : if (DEBUG) { System.out.println("CalloutFieldSpecLong ::= CalloutModifier Type Identifier"); }  //$NON-NLS-1$
+    case 286 : if (DEBUG) { System.out.println("CalloutFieldSpecLong ::= CalloutModifier Type Identifier"); }  //$NON-NLS-1$
 		    consumeFieldSpecLong();  
 			break;
  
-    case 286 : if (DEBUG) { System.out.println("BaseMethodSpecListShort ::= BaseMethodSpecListShort..."); }  //$NON-NLS-1$
+    case 289 : if (DEBUG) { System.out.println("BaseMethodSpecListShort ::= BaseMethodSpecListShort..."); }  //$NON-NLS-1$
 		    consumeMethodSpecList();  
 			break;
  
-    case 290 : if (DEBUG) { System.out.println("MethodSpecListLong ::= MethodSpecListLong COMMA..."); }  //$NON-NLS-1$
+    case 293 : if (DEBUG) { System.out.println("MethodSpecListLong ::= MethodSpecListLong COMMA..."); }  //$NON-NLS-1$
 		    consumeMethodSpecList();  
 			break;
  
-    case 291 : if (DEBUG) { System.out.println("PrecedenceDeclaration ::= precedence BindingNames..."); }  //$NON-NLS-1$
+    case 294 : if (DEBUG) { System.out.println("PrecedenceDeclaration ::= precedence BindingNames..."); }  //$NON-NLS-1$
 		    consumePrecedenceDeclaration(false);  
 			break;
  
-    case 292 : if (DEBUG) { System.out.println("PrecedenceDeclaration ::= precedence after BindingNames"); }  //$NON-NLS-1$
+    case 295 : if (DEBUG) { System.out.println("PrecedenceDeclaration ::= precedence after BindingNames"); }  //$NON-NLS-1$
 		    consumePrecedenceDeclaration(true);  
 			break;
  
-    case 294 : if (DEBUG) { System.out.println("BindingNames ::= BindingNames COMMA BindingName"); }  //$NON-NLS-1$
+    case 297 : if (DEBUG) { System.out.println("BindingNames ::= BindingNames COMMA BindingName"); }  //$NON-NLS-1$
 		    consumeBindingNames();  
 			break;
  
-    case 295 : if (DEBUG) { System.out.println("BindingName ::= Name"); }  //$NON-NLS-1$
+    case 298 : if (DEBUG) { System.out.println("BindingName ::= Name"); }  //$NON-NLS-1$
 		    consumeBindingName();  
 			break;
  
-    case 296 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); }  //$NON-NLS-1$
+    case 299 : if (DEBUG) { System.out.println("StaticInitializer ::= StaticOnly Block"); }  //$NON-NLS-1$
 		    consumeStaticInitializer();  
 			break;
 
-    case 297 : if (DEBUG) { System.out.println("StaticOnly ::= static"); }  //$NON-NLS-1$
+    case 300 : if (DEBUG) { System.out.println("StaticOnly ::= static"); }  //$NON-NLS-1$
 		    consumeStaticOnly();  
 			break;
  
-    case 298 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); }  //$NON-NLS-1$
+    case 301 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader MethodBody"); }  //$NON-NLS-1$
 		    consumeConstructorDeclaration() ;  
 			break;
  
-    case 299 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); }  //$NON-NLS-1$
+    case 302 : if (DEBUG) { System.out.println("ConstructorDeclaration ::= ConstructorHeader SEMICOLON"); }  //$NON-NLS-1$
 		    consumeInvalidConstructorDeclaration() ;  
 			break;
  
-    case 300 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); }  //$NON-NLS-1$
+    case 303 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= this LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(0, THIS_CALL);  
 			break;
  
-    case 301 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); }  //$NON-NLS-1$
+    case 304 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments this"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(0,THIS_CALL);  
 			break;
  
-    case 302 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); }  //$NON-NLS-1$
+    case 305 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= super LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(0,SUPER_CALL);  
 			break;
  
-    case 303 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 306 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(0,SUPER_CALL);  
 			break;
  
-    case 304 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= tsuper LPAREN..."); }  //$NON-NLS-1$
+    case 307 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= tsuper LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(0,TSUPER_CALL);  
 			break;
  
-    case 305 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT tsuper LPAREN"); }  //$NON-NLS-1$
+    case 308 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT tsuper LPAREN"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(2,TSUPER_CALL);  
 			break;
  
-    case 306 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); }  //$NON-NLS-1$
+    case 309 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT super..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(1, SUPER_CALL);  
 			break;
  
-    case 307 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
+    case 310 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(1, SUPER_CALL);  
 			break;
  
-    case 308 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); }  //$NON-NLS-1$
+    case 311 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT super LPAREN"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(2, SUPER_CALL);  
 			break;
  
-    case 309 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
+    case 312 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(2, SUPER_CALL);  
 			break;
  
-    case 310 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); }  //$NON-NLS-1$
+    case 313 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT this..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(1, THIS_CALL);  
 			break;
  
-    case 311 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
+    case 314 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Primary DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(1, THIS_CALL);  
 			break;
  
-    case 312 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); }  //$NON-NLS-1$
+    case 315 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT this LPAREN"); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocation(2, THIS_CALL);  
 			break;
  
-    case 313 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
+    case 316 : if (DEBUG) { System.out.println("ExplicitConstructorInvocation ::= Name DOT..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationWithTypeArguments(2, THIS_CALL);  
 			break;
  
-    case 314 : if (DEBUG) { System.out.println("BaseConstructorExpression ::= base LPAREN..."); }  //$NON-NLS-1$
+    case 317 : if (DEBUG) { System.out.println("BaseConstructorExpression ::= base LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationBase(0);  
 			break;
  
-    case 315 : if (DEBUG) { System.out.println("BaseConstructorInvocation ::= base LPAREN..."); }  //$NON-NLS-1$
+    case 318 : if (DEBUG) { System.out.println("BaseConstructorInvocation ::= base LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationBase(1);  
 			break;
  
-    case 316 : if (DEBUG) { System.out.println("BaseConstructorInvocation ::= Primary DOT base LPAREN..."); }  //$NON-NLS-1$
+    case 319 : if (DEBUG) { System.out.println("BaseConstructorInvocation ::= Primary DOT base LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationBase(2);  
 			break;
  
-    case 317 : if (DEBUG) { System.out.println("BaseConstructorInvocation ::= Name DOT base LPAREN..."); }  //$NON-NLS-1$
+    case 320 : if (DEBUG) { System.out.println("BaseConstructorInvocation ::= Name DOT base LPAREN..."); }  //$NON-NLS-1$
 		    consumeExplicitConstructorInvocationBase(3);  
 			break;
  
-    case 318 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); }  //$NON-NLS-1$
+    case 321 : if (DEBUG) { System.out.println("InterfaceDeclaration ::= InterfaceHeader InterfaceBody"); }  //$NON-NLS-1$
 		    consumeInterfaceDeclaration();  
 			break;
  
-    case 319 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); }  //$NON-NLS-1$
+    case 322 : if (DEBUG) { System.out.println("InterfaceHeader ::= InterfaceHeaderName..."); }  //$NON-NLS-1$
 		    consumeInterfaceHeader();  
 			break;
  
-    case 320 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); }  //$NON-NLS-1$
+    case 323 : if (DEBUG) { System.out.println("InterfaceHeaderName ::= InterfaceHeaderName1..."); }  //$NON-NLS-1$
 		    consumeTypeHeaderNameWithTypeParameters();  
 			break;
  
-    case 322 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); }  //$NON-NLS-1$
+    case 325 : if (DEBUG) { System.out.println("InterfaceHeaderName1 ::= Modifiersopt interface..."); }  //$NON-NLS-1$
 		    consumeInterfaceHeaderName1();  
 			break;
  
-    case 323 : if (DEBUG) { System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); }  //$NON-NLS-1$
+    case 326 : if (DEBUG) { System.out.println("InterfaceHeaderExtends ::= extends InterfaceTypeList"); }  //$NON-NLS-1$
 		    consumeInterfaceHeaderExtends();  
 			break;
  
-    case 326 : if (DEBUG) { System.out.println("InterfaceMemberDeclarations ::=..."); }  //$NON-NLS-1$
+    case 329 : if (DEBUG) { System.out.println("InterfaceMemberDeclarations ::=..."); }  //$NON-NLS-1$
 		    consumeInterfaceMemberDeclarations();  
 			break;
  
-    case 327 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 330 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyTypeDeclaration();  
 			break;
  
-    case 329 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
+    case 332 : if (DEBUG) { System.out.println("InterfaceMemberDeclaration ::= MethodHeader MethodBody"); }  //$NON-NLS-1$
 		    consumeInvalidMethodDeclaration();  
 			break;
  
-    case 330 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
-		    consumeInvalidConstructorDeclaration(true);   
+    case 333 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
+		    consumeInvalidConstructorDeclaration(true);  
 			break;
  
-    case 331 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
-		    consumeInvalidConstructorDeclaration(false);   
+    case 334 : if (DEBUG) { System.out.println("InvalidConstructorDeclaration ::= ConstructorHeader..."); }  //$NON-NLS-1$
+		    consumeInvalidConstructorDeclaration(false);  
 			break;
  
-    case 343 : if (DEBUG) { System.out.println("PushLeftBrace ::="); }  //$NON-NLS-1$
+    case 346 : if (DEBUG) { System.out.println("PushLeftBrace ::="); }  //$NON-NLS-1$
 		    consumePushLeftBrace();  
 			break;
  
-    case 344 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); }  //$NON-NLS-1$
+    case 347 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace ,opt RBRACE"); }  //$NON-NLS-1$
 		    consumeEmptyArrayInitializer();  
 			break;
  
-    case 345 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
+    case 348 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
 		    consumeArrayInitializer();  
 			break;
  
-    case 346 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
+    case 349 : if (DEBUG) { System.out.println("ArrayInitializer ::= LBRACE PushLeftBrace..."); }  //$NON-NLS-1$
 		    consumeArrayInitializer();  
 			break;
  
-    case 348 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); }  //$NON-NLS-1$
+    case 351 : if (DEBUG) { System.out.println("VariableInitializers ::= VariableInitializers COMMA..."); }  //$NON-NLS-1$
 		    consumeVariableInitializers();  
 			break;
  
-    case 349 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); }  //$NON-NLS-1$
+    case 352 : if (DEBUG) { System.out.println("Block ::= OpenBlock LBRACE BlockStatementsopt RBRACE"); }  //$NON-NLS-1$
 		    consumeBlock();  
 			break;
  
-    case 350 : if (DEBUG) { System.out.println("OpenBlock ::="); }  //$NON-NLS-1$
+    case 353 : if (DEBUG) { System.out.println("OpenBlock ::="); }  //$NON-NLS-1$
 		    consumeOpenBlock() ;  
 			break;
  
-    case 352 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); }  //$NON-NLS-1$
+    case 355 : if (DEBUG) { System.out.println("BlockStatements ::= BlockStatements BlockStatement"); }  //$NON-NLS-1$
 		    consumeBlockStatements() ;  
 			break;
  
-    case 356 : if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration"); }  //$NON-NLS-1$
+    case 359 : if (DEBUG) { System.out.println("BlockStatement ::= InterfaceDeclaration"); }  //$NON-NLS-1$
 		    consumeInvalidInterfaceDeclaration();  
 			break;
  
-    case 357 : if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration"); }  //$NON-NLS-1$
+    case 360 : if (DEBUG) { System.out.println("BlockStatement ::= AnnotationTypeDeclaration"); }  //$NON-NLS-1$
 		    consumeInvalidAnnotationTypeDeclaration();  
 			break;
  
-    case 358 : if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration"); }  //$NON-NLS-1$
+    case 361 : if (DEBUG) { System.out.println("BlockStatement ::= EnumDeclaration"); }  //$NON-NLS-1$
 		    consumeInvalidEnumDeclaration();  
 			break;
  
-    case 359 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); }  //$NON-NLS-1$
+    case 362 : if (DEBUG) { System.out.println("LocalVariableDeclarationStatement ::=..."); }  //$NON-NLS-1$
 		    consumeLocalVariableDeclarationStatement();  
 			break;
  
-    case 360 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); }  //$NON-NLS-1$
+    case 363 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Type PushModifiers..."); }  //$NON-NLS-1$
 		    consumeLocalVariableDeclaration();  
 			break;
  
-    case 361 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); }  //$NON-NLS-1$
+    case 364 : if (DEBUG) { System.out.println("LocalVariableDeclaration ::= Modifiers Type..."); }  //$NON-NLS-1$
 		    consumeLocalVariableDeclaration();  
 			break;
  
-    case 362 : if (DEBUG) { System.out.println("PushModifiers ::="); }  //$NON-NLS-1$
+    case 365 : if (DEBUG) { System.out.println("PushModifiers ::="); }  //$NON-NLS-1$
 		    consumePushModifiers();  
 			break;
  
-    case 363 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); }  //$NON-NLS-1$
+    case 366 : if (DEBUG) { System.out.println("PushModifiersForHeader ::="); }  //$NON-NLS-1$
 		    consumePushModifiersForHeader();  
 			break;
  
-    case 364 : if (DEBUG) { System.out.println("PushRealModifiers ::="); }  //$NON-NLS-1$
+    case 367 : if (DEBUG) { System.out.println("PushRealModifiers ::="); }  //$NON-NLS-1$
 		    consumePushRealModifiers();  
 			break;
  
-    case 391 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 395 : if (DEBUG) { System.out.println("EmptyStatement ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeEmptyStatement();  
 			break;
  
-    case 392 : if (DEBUG) { System.out.println("LabeledStatement ::= Label COLON Statement"); }  //$NON-NLS-1$
+    case 396 : if (DEBUG) { System.out.println("LabeledStatement ::= Label COLON Statement"); }  //$NON-NLS-1$
 		    consumeStatementLabel() ;  
 			break;
  
-    case 393 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Label COLON..."); }  //$NON-NLS-1$
+    case 397 : if (DEBUG) { System.out.println("LabeledStatementNoShortIf ::= Label COLON..."); }  //$NON-NLS-1$
 		    consumeStatementLabel() ;  
 			break;
  
-    case 394 : if (DEBUG) { System.out.println("Label ::= Identifier"); }  //$NON-NLS-1$
+    case 398 : if (DEBUG) { System.out.println("Label ::= Identifier"); }  //$NON-NLS-1$
 		    consumeLabel() ;  
 			break;
  
-     case 395 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); }  //$NON-NLS-1$
+     case 399 : if (DEBUG) { System.out.println("ExpressionStatement ::= StatementExpression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeExpressionStatement();  
 			break;
  
-    case 405 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 409 : if (DEBUG) { System.out.println("IfThenStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementIfNoElse();  
 			break;
  
-    case 406 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 410 : if (DEBUG) { System.out.println("IfThenElseStatement ::= if LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementIfWithElse();  
 			break;
  
-    case 407 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); }  //$NON-NLS-1$
+    case 411 : if (DEBUG) { System.out.println("IfThenElseStatementNoShortIf ::= if LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementIfWithElse();  
 			break;
  
-    case 408 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 412 : if (DEBUG) { System.out.println("SwitchStatement ::= switch LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementSwitch() ;  
 			break;
  
-    case 409 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); }  //$NON-NLS-1$
+    case 413 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE RBRACE"); }  //$NON-NLS-1$
 		    consumeEmptySwitchBlock() ;  
 			break;
  
-    case 412 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); }  //$NON-NLS-1$
+    case 416 : if (DEBUG) { System.out.println("SwitchBlock ::= LBRACE SwitchBlockStatements..."); }  //$NON-NLS-1$
 		    consumeSwitchBlock() ;  
 			break;
  
-    case 414 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); }  //$NON-NLS-1$
+    case 418 : if (DEBUG) { System.out.println("SwitchBlockStatements ::= SwitchBlockStatements..."); }  //$NON-NLS-1$
 		    consumeSwitchBlockStatements() ;  
 			break;
  
-    case 415 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
+    case 419 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
 		    consumeSwitchBlockStatement() ;  
 			break;
  
-    case 417 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
+    case 421 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
 		    consumeSwitchLabels() ;  
 			break;
  
-     case 418 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); }  //$NON-NLS-1$
+     case 422 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); }  //$NON-NLS-1$
 		    consumeCaseLabel();  
 			break;
  
-     case 419 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
+     case 423 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
 		    consumeDefaultLabel();  
 			break;
  
-    case 420 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 424 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementWhile() ;  
 			break;
  
-    case 421 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
+    case 425 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementWhile() ;  
 			break;
  
-    case 422 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
+    case 426 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementDo() ;  
 			break;
  
-    case 423 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
+    case 427 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
 		    consumeStatementFor() ;  
 			break;
  
-    case 424 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
+    case 428 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
 		    consumeStatementFor() ;  
 			break;
  
-    case 425 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
+    case 429 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
 		    consumeForInit() ;  
 			break;
  
-    case 429 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
+    case 433 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
 		    consumeStatementExpressionList() ;  
 			break;
  
-    case 430 : if (DEBUG) { System.out.println("WithinStatement ::= within LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 434 : if (DEBUG) { System.out.println("WithinStatement ::= within LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeWithinStatement();  
 			break;
  
-    case 431 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
+    case 435 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeSimpleAssertStatement() ;  
 			break;
  
-    case 432 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
+    case 436 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
 		    consumeAssertStatement() ;  
 			break;
  
-    case 433 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
+    case 437 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementBreak() ;  
 			break;
  
-    case 434 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); }  //$NON-NLS-1$
+    case 438 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementBreakWithLabel() ;  
 			break;
  
-    case 435 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
+    case 439 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementContinue() ;  
 			break;
  
-    case 436 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
+    case 440 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementContinueWithLabel() ;  
 			break;
  
-    case 437 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
+    case 441 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementReturn() ;  
 			break;
  
-    case 438 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
+    case 442 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementThrow();  
 			break;
  
-    case 439 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
+    case 443 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementSynchronized();  
 			break;
  
-    case 440 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
+    case 444 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
 		    consumeOnlySynchronized();  
 			break;
  
-    case 441 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
-		    consumeStatementTry(false);  
+    case 445 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
+		    consumeStatementTry(false, false);  
 			break;
  
-    case 442 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
-		    consumeStatementTry(true);  
+    case 446 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
+		    consumeStatementTry(true, false);  
 			break;
  
-    case 444 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
+    case 447 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
+		    consumeStatementTry(false, true);  
+			break;
+ 
+    case 448 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
+		    consumeStatementTry(true, true);  
+			break;
+ 
+    case 449 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); }  //$NON-NLS-1$
+		    consumeResourceSpecification();  
+			break;
+ 
+    case 450 : if (DEBUG) { System.out.println(";opt ::="); }  //$NON-NLS-1$
+		    consumeResourceOptionalTrailingSemiColon(false);  
+			break;
+ 
+    case 451 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeResourceOptionalTrailingSemiColon(true);  
+			break;
+ 
+    case 452 : if (DEBUG) { System.out.println("Resources ::= Resource"); }  //$NON-NLS-1$
+		    consumeSingleResource();  
+			break;
+ 
+    case 453 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); }  //$NON-NLS-1$
+		    consumeMultipleResources();  
+			break;
+ 
+    case 454 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); }  //$NON-NLS-1$
+		    consumeResourceOptionalTrailingSemiColon(true);  
+			break;
+ 
+    case 455 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); }  //$NON-NLS-1$
+		    consumeResourceAsLocalVariableDeclaration();  
+			break;
+ 
+    case 456 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); }  //$NON-NLS-1$
+		    consumeResourceAsLocalVariableDeclaration();  
+			break;
+ 
+    case 458 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
 		    consumeExitTryBlock();  
 			break;
  
-    case 446 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
+    case 460 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
 		    consumeCatches();  
 			break;
  
-    case 447 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
+    case 461 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
 		    consumeStatementCatch() ;  
 			break;
  
-    case 449 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
+    case 463 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
 		    consumeLeftParen();  
 			break;
  
-    case 450 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
+    case 464 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
 		    consumeRightParen();  
 			break;
  
-    case 455 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
+    case 469 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayThis();  
 			break;
  
-    case 456 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
+    case 470 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArray();  
 			break;
  
-    case 457 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
+    case 471 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayWithName();  
 			break;
  
-    case 461 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
+    case 475 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayNameThis();  
 			break;
  
-    case 462 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); }  //$NON-NLS-1$
+    case 476 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT super"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayNameSuper();  
 			break;
  
-    case 463 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
+    case 477 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayName();  
 			break;
  
-    case 464 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
+    case 478 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayArrayType();  
 			break;
  
-    case 465 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
+    case 479 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayPrimitiveArrayType();  
 			break;
  
-    case 466 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
+    case 480 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayPrimitiveType();  
 			break;
  
-    case 467 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
+    case 481 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
 		    consumeRoleClassLiteral();  
 			break;
  
-    case 470 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
+    case 484 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
 		    consumeAllocationHeader();  
 			break;
  
-    case 471 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
+    case 485 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionWithTypeArguments();  
 			break;
  
-    case 472 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN"); }  //$NON-NLS-1$
+    case 486 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType LPAREN"); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpression();  
 			break;
  
-    case 473 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+    case 487 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
 			break;
  
-    case 474 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+    case 488 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualified() ;  
 			break;
  
-    case 475 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+    case 489 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualified() ;  
 			break;
  
-    case 476 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+    case 490 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
 			break;
  
-    case 477 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); }  //$NON-NLS-1$
+    case 491 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT"); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionName() ;  
 			break;
  
-    case 478 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); }  //$NON-NLS-1$
+    case 492 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); }  //$NON-NLS-1$
 		    consumeClassBodyopt();  
 			break;
  
-    case 480 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+    case 494 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
 		    consumeEnterAnonymousClassBody(false);  
 			break;
  
-    case 481 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); }  //$NON-NLS-1$
+    case 495 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); }  //$NON-NLS-1$
 		    consumeClassBodyopt();  
 			break;
  
-    case 483 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+    case 497 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
 		    consumeEnterAnonymousClassBody(true);  
 			break;
  
-    case 485 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
+    case 499 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
 		    consumeArgumentList();  
 			break;
  
-    case 486 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
+    case 500 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
 		    consumeArrayCreationHeader();  
 			break;
  
-    case 487 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
+    case 501 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
 		    consumeArrayCreationHeader();  
 			break;
  
-    case 488 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+    case 502 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithoutInitializer();  
 			break;
  
-    case 489 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
+    case 503 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithInitializer();  
 			break;
  
-    case 490 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+    case 504 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithoutInitializer();  
 			break;
  
-    case 491 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
+    case 505 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithInitializer();  
 			break;
  
-    case 493 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
+    case 507 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
 		    consumeDimWithOrWithOutExprs();  
 			break;
  
-     case 495 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
+     case 509 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
 		    consumeDimWithOrWithOutExpr();  
 			break;
  
-     case 496 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
+     case 510 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
 		    consumeDims();  
 			break;
  
-     case 499 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
+     case 513 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
 		    consumeOneDimLoop();  
 			break;
  
-    case 500 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
+    case 514 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(false);  
 			break;
  
-    case 501 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
+    case 515 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(true);  
 			break;
  
-    case 502 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+    case 516 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
 		    consumeMethodInvocationName();  
 			break;
  
-    case 503 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 517 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationNameWithTypeArguments();  
 			break;
  
-    case 504 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 518 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimaryWithTypeArguments();  
 			break;
  
-    case 505 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 519 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimary();  
 			break;
  
-    case 506 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 520 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationSuperWithTypeArguments();  
 			break;
  
-    case 507 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 521 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationSuper();  
 			break;
  
-    case 508 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 522 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationTSuper(UNQUALIFIED);  
 			break;
  
-    case 509 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 523 : if (DEBUG) { System.out.println("MethodInvocation ::= tsuper DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationTSuperWithTypeArguments(0);  
 			break;
  
-    case 510 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT Identifier..."); }  //$NON-NLS-1$
+    case 524 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT Identifier..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationTSuper(QUALIFIED);  
 			break;
  
-    case 511 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT..."); }  //$NON-NLS-1$
+    case 525 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT tsuper DOT..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationTSuperWithTypeArguments(2);  
 			break;
  
-    case 512 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 526 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationBase(false);  
 			break;
  
-    case 513 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 527 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationBaseWithTypeArguments(false);  
 			break;
  
-    case 514 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT Identifier..."); }  //$NON-NLS-1$
+    case 528 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT Identifier..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationBase(true);  
 			break;
  
-    case 515 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT..."); }  //$NON-NLS-1$
+    case 529 : if (DEBUG) { System.out.println("MethodInvocation ::= base DOT super DOT..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationBaseWithTypeArguments(true);  
 			break;
  
-    case 516 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
+    case 530 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
 		    consumeArrayAccess(true);  
 			break;
  
-    case 517 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
+    case 531 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
 		    consumeArrayAccess(false);  
 			break;
  
-    case 518 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
+    case 532 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
 		    consumeArrayAccess(false);  
 			break;
  
-    case 520 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
+    case 534 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
 		    consumePostfixExpression();  
 			break;
  
-    case 523 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
+    case 537 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS,true);  
 			break;
  
-    case 524 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
+    case 538 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS,true);  
 			break;
  
-    case 525 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
+    case 539 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
 		    consumePushPosition();  
 			break;
  
-    case 528 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+    case 542 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 529 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+    case 543 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 531 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
+    case 545 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS,false);  
 			break;
  
-    case 532 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
+    case 546 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS,false);  
 			break;
  
-    case 534 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
+    case 548 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
 			break;
  
-    case 535 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
+    case 549 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.NOT);  
 			break;
  
-    case 537 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
+    case 551 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithPrimitiveType();  
 			break;
  
-    case 538 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+    case 552 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithGenericsArray();  
 			break;
  
-    case 539 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+    case 553 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithQualifiedGenericsArray();  
 			break;
  
-    case 540 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
+    case 554 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
 		    consumeCastExpressionLL1();  
 			break;
  
-    case 541 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); }  //$NON-NLS-1$
+    case 555 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims PushRPAREN..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithNameArray();  
 			break;
  
-    case 542 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
+    case 556 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
 		    consumeOnlyTypeArgumentsForCastExpression();  
 			break;
  
-    case 543 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
+    case 557 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpression();  
 			break;
  
-    case 544 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
+    case 558 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionLL1();  
 			break;
  
-    case 545 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
+    case 559 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionWithQualifiedGenerics();  
 			break;
  
-    case 547 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 561 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
 			break;
  
-    case 548 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 562 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.DIVIDE);  
 			break;
  
-    case 549 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 563 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.REMAINDER);  
 			break;
  
-    case 551 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
+    case 565 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 552 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
+    case 566 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 554 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
+    case 568 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 555 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 569 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 556 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 570 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 558 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
+    case 572 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS);  
 			break;
  
-    case 559 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
+    case 573 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER);  
 			break;
  
-    case 560 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
+    case 574 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 561 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
+    case 575 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 563 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
+    case 577 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
 		    consumeInstanceOfExpression();  
 			break;
  
-    case 565 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
+    case 579 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 566 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
+    case 580 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 568 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
+    case 582 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND);  
 			break;
  
-    case 570 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
+    case 584 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.XOR);  
 			break;
  
-    case 572 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
+    case 586 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR);  
 			break;
  
-    case 574 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
+    case 588 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND_AND);  
 			break;
  
-    case 576 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+    case 590 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR_OR);  
 			break;
  
-    case 578 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+    case 592 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
 		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 581 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
+    case 595 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
 		    consumeAssignment();  
 			break;
  
-    case 583 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
+    case 597 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
 		    ignoreExpressionAssignment(); 
 			break;
  
-    case 584 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
+    case 598 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(EQUAL);  
 			break;
  
-    case 585 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
+    case 599 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(MULTIPLY);  
 			break;
  
-    case 586 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
+    case 600 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(DIVIDE);  
 			break;
  
-    case 587 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
+    case 601 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(REMAINDER);  
 			break;
  
-    case 588 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
+    case 602 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(PLUS);  
 			break;
  
-    case 589 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
+    case 603 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(MINUS);  
 			break;
  
-    case 590 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 604 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(LEFT_SHIFT);  
 			break;
  
-    case 591 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 605 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(RIGHT_SHIFT);  
 			break;
  
-    case 592 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 606 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 593 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
+    case 607 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(AND);  
 			break;
  
-    case 594 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
+    case 608 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(XOR);  
 			break;
  
-    case 595 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
+    case 609 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(OR);  
 			break;
  
-    case 599 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
+    case 613 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyExpression();  
 			break;
  
-    case 604 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 618 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyClassBodyDeclarationsopt();  
 			break;
  
-    case 605 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+    case 619 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclarationsopt();  
 			break;
  
-     case 606 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
+     case 620 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
 		    consumeDefaultModifiers();  
 			break;
  
-    case 607 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
+    case 621 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
 		    consumeModifiers();  
 			break;
  
-    case 608 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
+    case 622 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyBlockStatementsopt();  
 			break;
  
-     case 610 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
+     case 624 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyDimsopt();  
 			break;
  
-     case 612 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
+     case 626 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyArgumentListopt();  
 			break;
  
-    case 616 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
+    case 630 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
 		    consumeFormalParameterListopt();  
 			break;
  
-     case 620 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+     case 634 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyInterfaceMemberDeclarationsopt();  
 			break;
  
-     case 621 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+     case 635 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeInterfaceMemberDeclarationsopt();  
 			break;
  
-    case 622 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
+    case 636 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
 		    consumeNestedType();  
 			break;
 
-     case 623 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
+     case 637 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyForInitopt();  
 			break;
  
-     case 625 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
+     case 639 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyForUpdateopt();  
 			break;
  
-     case 629 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
+     case 643 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyCatchesopt();  
 			break;
  
-     case 631 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
+     case 645 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
 		    consumeEnumDeclaration();  
 			break;
  
-     case 632 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
+     case 646 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
 		    consumeEnumHeader();  
 			break;
  
-     case 633 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
+     case 647 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
 		    consumeEnumHeaderName();  
 			break;
  
-     case 634 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); }  //$NON-NLS-1$
+     case 648 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); }  //$NON-NLS-1$
 		    consumeEnumHeaderNameWithTypeParameters();  
 			break;
  
-     case 635 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
+     case 649 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
 		    consumeEnumBodyNoConstants();  
 			break;
  
-     case 636 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
+     case 650 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
 		    consumeEnumBodyNoConstants();  
 			break;
  
-     case 637 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
+     case 651 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
 		    consumeEnumBodyWithConstants();  
 			break;
  
-     case 638 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
+     case 652 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
 		    consumeEnumBodyWithConstants();  
 			break;
  
-    case 640 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
+    case 654 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
 		    consumeEnumConstants();  
 			break;
  
-    case 641 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
+    case 655 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
 		    consumeEnumConstantHeaderName();  
 			break;
  
-    case 642 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
+    case 656 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
 		    consumeEnumConstantHeader();  
 			break;
  
-    case 643 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
+    case 657 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
 		    consumeEnumConstantWithClassBody();  
 			break;
  
-    case 644 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
+    case 658 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
 		    consumeEnumConstantNoClassBody();  
 			break;
  
-    case 645 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+    case 659 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
 		    consumeArguments();  
 			break;
  
-    case 646 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
+    case 660 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyArguments();  
 			break;
  
-    case 648 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
+    case 662 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
 		    consumeEnumDeclarations();  
 			break;
  
-    case 649 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 663 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyEnumDeclarations();  
 			break;
  
-    case 651 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
+    case 665 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatement();  
 			break;
  
-    case 652 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
+    case 666 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatement();  
 			break;
  
-    case 653 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); }  //$NON-NLS-1$
+    case 667 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeaderInit(false);  
 			break;
  
-    case 654 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); }  //$NON-NLS-1$
+    case 668 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeaderInit(true);  
 			break;