Basic merge with v_B14a for 3.7M2 
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
deleted file mode 100644
index fc466c9..0000000
--- a/org.eclipse.jdt.core/.settings/.api_filters
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jdt.core" version="2">
-    <resource path="dom/org/eclipse/jdt/core/dom/ASTParser.java" type="org.eclipse.jdt.core.dom.ASTParser">
-        <filter id="1142947843">
-            <message_arguments>
-                <message_argument value="3.5.2"/>
-                <message_argument value="setIgnoreMethodBodies(boolean)"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="model/org/eclipse/jdt/core/ICompilationUnit.java" type="org.eclipse.jdt.core.ICompilationUnit">
-        <filter id="1210056707">
-            <message_arguments>
-                <message_argument value="3.5.2"/>
-                <message_argument value="IGNORE_METHOD_BODIES"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="search/org/eclipse/jdt/core/search/TypeNameMatch.java" type="org.eclipse.jdt.core.search.TypeNameMatch">
-        <filter id="336744520">
-            <message_arguments>
-                <message_argument value="org.eclipse.jdt.core.search.TypeNameMatch"/>
-            </message_arguments>
-        </filter>
-    </resource>
-</component>
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
index 1a51c49..09d02cb 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/core/compiler/batch/BatchCompiler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -49,7 +49,7 @@
 	 * @return whether the compilation completed successfully
 	 */
 	public static boolean compile(String commandLine, PrintWriter outWriter, PrintWriter errWriter, CompilationProgress progress) {
-		return Main.compile(Main.tokenize(commandLine), outWriter, errWriter, progress);
+		return compile(Main.tokenize(commandLine), outWriter, errWriter, progress);
 	}
 
 	/**
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
index a592994..e6d32fd 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java
@@ -136,6 +136,13 @@
 	if (binaryExists) {
 		try {
 			ClassFileReader reader = ClassFileReader.read(this.path + qualifiedBinaryFileName);
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=321115, package names are to be treated case sensitive.
+			String typeSearched = qualifiedPackageName.length() > 0 ? 
+					qualifiedPackageName.replace(File.separatorChar, '/') + "/" + fileName //$NON-NLS-1$
+					: fileName;
+			if (!CharOperation.equals(reader.getName(), typeSearched.toCharArray())) {
+				reader = null;
+			}
 			if (reader != null)
 				return new NameEnvironmentAnswer(
 						reader,
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 11c4004..6ad427b 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,7 +1,7 @@
 #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.A58, 3.6.0
+compiler.version = 0.B14a, 3.7.0 M3
 compiler.copyright = Copyright IBM Corp 2000, 2010. All rights reserved.
 
 ###{ObjectTeams:
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index bfa4eff..7137c5e 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -3,14 +3,14 @@
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta name="Author" content="IBM">
-   <title>JDT/Core Release Notes 3.6</title>
+   <title>JDT/Core Release Notes 3.7</title>
    <link rel="stylesheet" href="jdt_core_style.css" charset="iso-8859-1" type="text/css">
 </head>
 <body text="#000000" bgcolor="#FFFFFF">
 <table border=0 cellspacing=5 cellpadding=2 width="100%" >
   <tr>
     <td align="left" width="72%" class="title1">
-      <font size="+3"><b>jdt core - build notes 3.6 stream</b></font>
+      <font size="+3"><b>jdt core - build notes 3.7 stream</b></font>
     </td>
   </tr>
   <tr><td align="left" width="72%" class="title2"><font size="-2">Java development tools core</font></td></tr>
@@ -21,8 +21,8 @@
 	  Here are the build notes for the Eclipse JDT/Core plug-in project
 	  <a href="http://www.eclipse.org/jdt/core/index.php"><b>org.eclipse.jdt.core</b></a>,
 	  describing <a href="https://bugs.eclipse.org/bugs" target=new>bug</a> resolution and substantial changes in the <a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core"><b>HEAD</b></a> branch.
-	  For more information on 3.6 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.6/index.php#release-plan">JDT/Core release plan</a>,
-	  the next <a href="http://www.eclipse.org/jdt/core/r3.6/index.php#milestone-plan">milestone plan</a>,
+	  For more information on 3.7 planning, please refer to <a href="http://www.eclipse.org/jdt/core/r3.7/index.php#release-plan">JDT/Core release plan</a>,
+	  the next <a href="http://www.eclipse.org/jdt/core/r3.7/index.php#milestone-plan">milestone plan</a>,
 	  the overall <a href="http://www.eclipse.org/eclipse/development/eclipse_project_plan_3_6.html">official plan</a>,
 	  or the <a href="http://www.eclipse.org/eclipse/platform-releng/buildSchedule.html">build schedule</a>.
 	  This present document covers all changes since Release 3.5 (also see a summary of <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/API_changes.html">API changes</a>).
@@ -40,2238 +40,547 @@
 	</td>
   </tr>
 </table>
-<a name="v_A58"></a>
+<a name="v_B14a"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6 - June 3, 2010 - 3.6.0
-<br>Project org.eclipse.jdt.core v_A58
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A58">cvs</a>).
+Eclipse SDK 3.7M3 - September 21, 2010 - 3.7.0 M3
+<br>Project org.eclipse.jdt.core v_B14a
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B14a">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=315568">315568</a>
-improve Javadoc of SearchPattern#createPattern(String, int, int, int)
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325567">325567</a>
+A blocking &quot;java.lang.IllegalArgumentException: info cannot be null&quot; exception
 
-<a name="v_A57"></a>
+<a name="v_B13a"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6RC4 - June 3, 2010 - 3.6.0 RC4
-<br>Project org.eclipse.jdt.core v_A57
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A57">cvs</a>).
+Eclipse SDK 3.7M2 - September 21, 2010 - 3.7.0 M2
+<br>Project org.eclipse.jdt.core v_B13a
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B13a">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=325755">325755</a>
+[compiler] wrong initialization state after conditional expression
+
+<a name="v_B13"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M2 - September 15, 2010
+<br>Project org.eclipse.jdt.core v_B13
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B13">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=325229">325229</a>
+[compiler] eclipse compiler differs from javac when assert is present  (FUP of bug 319510)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325270">325270</a>
+[content assist] Parameter names are not displayed for static inner class of an external jar
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=325321">325321</a>
+[compiler] Synthetic constructors for non-static inner classes can exceed 255 parameters -&gt; ClassFormatError
+
+<a name="v_B12a"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M2 - September 13, 2010
+<br>Project org.eclipse.jdt.core v_B12a
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B12a">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=324840">324840</a>
+[compiler] Improving debug strings for Break statement, IntLiteral and CaseStatement
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324848">324848</a>
+[1.6][compiler] NullPointerException when trying to synchronize on non-existing outer class instance
+
+<a name="v_B11"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M2 - September 9, 2010 - 3.7.0 M2
+<br>Project org.eclipse.jdt.core v_B11
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B11">cvs</a>).
 <h2>What's new in this drop</h2>
 <ul>
-<li>Use default disabling/enabling tags in the samples of the Javadoc comments
-of the formatter constants <code>FORMATTER_DISABLING_TAG</code> and
-<code>FORMATTER_ENABLING_TAG</code>.</li>
-<li>Fixed minor javadoc issues of <code>createStrictHierarchyScope()</code>.</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=314709">314709</a>
-Clarify -encoding &lt;encoding name&gt; in jdt_api_compile.htm
-
-<a name="v_A56"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC3 - May 27, 2010 - 3.6.0 RC3
-<br>Project org.eclipse.jdt.core v_A56
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A56">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=313890">313890</a>
-Migration guide to 3.6 for containers with MANIFEST-referred entries
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313965">313965</a>
-Breaking change in classpath container API
-
-<a name="v_A55"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC3 - May 25, 2010
-<br>Project org.eclipse.jdt.core v_A55
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A55">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=313706">313706</a>
-Replace ie. with i.e. in jdt.core documentation
-
-<a name="v_A54"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC2 - May 20, 2010 - 3.6.0 RC2
-<br>Project org.eclipse.jdt.core v_A54
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A54">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>
-Added a new preference to force the formatter to try to keep nested expressions on one line.
-<p>
-This new preference is controlled with the option:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_WRAP_OUTER_EXPRESSIONS_WHEN_NESTED</code>
+<li>Adding missing API methods on org.eclipse.jdt.core.ILocalVariable (see details in <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48420">bug 48420</a>):
 <pre>
-/**
- * FORMATTER / Option to wrap outer expressions in nested expressions
- *     - option id:         "org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested"
- *     - possible values:   { TRUE, FALSE }
- *     - default:           TRUE
- *
- * This option changes the formatter behavior when nested method calls are encountered.
- * Since 3.6, the formatter tries to wrap outermost method calls first to have a better output.
- * For example, let's say we are using the Eclipse built-in profile with a max line width=40+space for tab policy.
- * Then consider the following snippet:
- *
- * public class X01 {
- *     void test() {
- *         foo(bar(1, 2, 3, 4), bar(5, 6, 7, 8));
- *     }
- * }
- *
- * With this new strategy, the formatter will wrap the line earlier, between the arguments of the message call
- * for this example, and then it will allow to keep each nested call on a single line.
- * Hence, the output will be:
- *
- * public class X01 {
- *     void test() {
- *         foo(bar(1, 2, 3, 4),
- *             bar(5, 6, 7, 8));
- *     }
- * }
- *
- * Important notes:
- * 1. This new behavior is automatically activated (i.e. the default value for this preference is {@link #TRUE}).
- *    If the backward compatibility regarding previous versions' formatter behavior (i.e. before 3.6 version) is necessary,
- *    then the preference needs to be set to {@link #FALSE} to retrieve the previous formatter behavior.
- * 2. The new strategy currently only applies to nested method calls, but might be extended to other nested expressions in future versions
- * 
- * @see #TRUE
- * @see #FALSE
- * @since 3.6
- */
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313524">313524</a> for more details.
-</li>
-</ul>
+    /**
+     * Returns true if this local variable is a method parameter, false otherwise.
+     * 
+     * @return true if this local variable is a method parameter, false otherwise
+     * @since 3.7
+     */
+    boolean isParameter();
 
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313524">313524</a>
-[formatter] Add preference for improved lines wrapping in nested method calls
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313109">313109</a>
-@SuppressWarnings on multiple locals is marked unnecessary if any local is never used
+    /**
+     * Returns the modifier flags for this local variable. The flags can be examined using class.
+     * 
+     * Note that only flags as indicated in the source are returned.
+     *
+     * @return the modifier flags for this local variable
+     * @see Flags
+     * @since 3.7
+     */
+    int getFlags();
 
-<a name="v_A53"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC1 - May 12, 2010 - 3.6.0 RC1
-<br>Project org.eclipse.jdt.core v_A53
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A53">cvs</a>).
-<h2>What's new in this drop</h2>
+    /**
+     * Returns the declaring member of this local variable.
+     *
+     * This is a handle-only method.
+     *
+     * @return the declaring member of this local variable
+     * @since 3.7
+     */
+    IMember getDeclaringMember();
 
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=312326">312326</a>
-IllegalArgumentException using open type dialog
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310159">310159</a>
-Hang in JavaModel.getExternalTarget(JavaModel.java:333)
-
-<a name="v_A52"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC1 - May 11, 2010
-<br>Project org.eclipse.jdt.core v_A52
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A52">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=157847">157847</a>
-NPE in WildcardBinding.computeUniqueKey during code assist
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311849">311849</a>
-[quick fix] @SuppressWarnings does not work as expected inside a for loop
-
-<a name="v_A51"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC1 - May 8, 2010
-<br>Project org.eclipse.jdt.core v_A51
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A51">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=306170">306170</a>
-[perfs] Regression for FullSourceWorkspaceTypeHierarchyTests#testPerfAllTypes()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298844">298844</a>
-[formatter] New lines in empty method body wrong behavior
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311864">311864</a>
-[formatter] NPE with empty {@code }
-
-<a name="v_A50"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC1 - May 6, 2010
-<br>Project org.eclipse.jdt.core v_A50
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A50">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>
-Added a new preference to switch on/off the usage of the disabling/enabling tags of the formatter.
-<p>
-This new preference is controlled with the option:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_USE_ON_OFF_TAGS</code>
-<pre>
-/**
- * FORMATTER / Option to use the disabling and enabling tags defined respectively by the {@link #FORMATTER_DISABLING_TAG} and the {@link #FORMATTER_ENABLING_TAG} options.
- *     - option id:         "org.eclipse.jdt.core.formatter.use_on_off_tags"
- *     - possible values:   TRUE / FALSE
- *     - default:           FALSE
- * 
- * @since 3.6
- */
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311582">311582</a> for more details.
-</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311617">311617</a>
-[formatter] provide default tags to enable/disable formatter
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311582">311582</a>
-[formatter] Master switch to enable/disable on/off tags
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=307040">307040</a>
-Search Job with HierarchyScope on Object does not cancel
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302295">302295</a>
-After associating source folder with rt.jar project refresh takes exceedingly long time.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311048">311048</a>
-AbortCompilation propagated from CompilationUnitProblemFinder.process()
-
-<a name="v_A49"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6RC1 - May 4, 2010
-<br>Project org.eclipse.jdt.core v_A49
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A49">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=310811">310811</a>
-[perfs] Big regression on FullSourceWorkspaceFormatterTests#testFormatDefaultBigFile()
-
-<a name="v_A48"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - April 25, 2010 - 3.6.0 M7
-<br>Project org.eclipse.jdt.core v_A48
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A48">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=310330">310330</a>
-Add multiple encoding support for the batch compiler
-
-<a name="v_A47"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - April 25, 2010
-<br>Project org.eclipse.jdt.core v_A47
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A47">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=309835">309835</a>
-[formatter] adds blank lines on each run
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310213">310213</a>
-AIOOBE in IndexSelector.initializeIndexLocations()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309966">309966</a>
-IType#getKey() does not work for unresolved local ITypes
-
-<a name="v_A46"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - April 23, 2010
-<br>Project org.eclipse.jdt.core v_A46
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A46">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=59891">59891</a>
-[formatter] improve lines wrapping in nested method calls
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306172">306172</a>
-[perfs] Invalid test duration for FullSourceWorkspaceTypeHierarchyTests#testPerSuperTypes()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267091">267091</a>
-[content assist] After 'implements' interface members are not proposed
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=261534">261534</a>
-content assist after instanceof should also work after &amp;&amp;
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308980">308980</a>
-[content assist]An initializer inside a non-array field declaration confuses content assist
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310002">310002</a>
-ToolFactory.createScanner(..) should use workspace compliance
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291528">291528</a>
-Synchronize project warning/error settings to build.properties
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309787">309787</a>
-Extension point &quot;org.eclipse.jdt.core.codeFormatter&quot; is ignored
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=244820">244820</a>
-Content assist after 'instanceof' should also work in assignment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309706">309706</a>
-[formatter] doesn't work when code has three semicolons side by side
-
-<a name="v_A45"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - April 20, 2010
-<br>Project org.eclipse.jdt.core v_A45
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A45">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=305037">305037</a>
-missing story for attributes of referenced JARs in classpath containers
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305116">305116</a>
-[index] Improve performance of indexes results tables
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=236306">236306</a>
-[content assist] for method invocation in variable initializer should not guess variable
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302865">302865</a>
-Issue with &quot;import&quot; a class and &quot;import static&quot; a method with the same name
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309022">309022</a>
-[ImportRewrite] Add Import wrongly removes import for nested type
-
-<a name="v_A44"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - April 13, 2010
-<br>Project org.eclipse.jdt.core v_A44
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A44">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=308754">308754</a>
-CompilationUnit.rewrite messes up .class-literal in annotation instead of changing class to interface
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306519">306519</a>
-JavaCore#getReferencedClasspathEntries(IClasspathEntry, IJavaProject) should allow null project
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308428">308428</a>
-Possible problem to get corrections with surrogate characters
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=307295">307295</a>
-Task tags and task priorities
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308476">308476</a>
-Test ClasspathTests#testBug308150 fails on all platforms
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305043">305043</a>
-Internal error during classpath init
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=307486">307486</a>
-DBCS3.6: Fail to propose Ext-B labels with content assist in Java Editor
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308256">308256</a>
-DiagnosticListener always supplies Diagnostic.getSource()==null
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308356">308356</a>
-codeSelect(..) doesn't work for local variable with surrogate in name
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308245">308245</a>
-Valid code fails to compile in 3.6
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=307885">307885</a>
-Error message for instanceof &lt;parameterized type&gt; wrong arguments
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=249704">249704</a>
-[code assist] autocomplete with anonymous classes does stop working
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308150">308150</a>
-JAR with invalid Class-Path entry in MANIFEST.MF crashes the project
-
-<a name="v_A43"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - April 6, 2010
-<br>Project org.eclipse.jdt.core v_A43
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A43">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=306223">306223</a>
-[search] Searching for annotation references report all type references
-<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=307337">307337</a>
-[content assist] Default constructor should not be proposed for anonymous types
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306568">306568</a>
-[ImportRewrite] Add Import does not work for nested type when package is on-demand imported
-
-<a name="v_A42"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - March 30, 2010
-<br>Project org.eclipse.jdt.core v_A42
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A42">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=202634">202634</a>
-[codeassist] missing super proposal in specific source
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304394">304394</a>
-IJavaElement#getAttachedJavadoc(IProgressMonitor) should support referenced entries
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305122">305122</a>
-FUP of 302949
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306917">306917</a>
-Exception occurred during compilation unit conversion:
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306196">306196</a>
-[search] NPE while searching for annotation references in rt.jar of JRE 6.0
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658">288658</a>
-[compiler][1.5] Annotations visibility issues
-
-<a name="v_A41"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - March 23, 2010
-<br>Project org.eclipse.jdt.core v_A41
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A41">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=305518">305518</a>
-[formatter] Line inside &lt;pre&gt; tag is wrongly indented by one space when starting just after the star
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295825">295825</a>
-[formatter] Commentaries are running away after formatting are used
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306477">306477</a>
-Indexer(?) fails to recognise enum as a type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305830">305830</a>
-[formatter] block comment should not be formatted when a non-nls tag is on the same line
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300031">300031</a>
-The deprecation warning for a type should not include the package name
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306078">306078</a>
-Navigate to Inaccessible Field
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209479">209479</a>
-infinite loop in BindingKey when signatures are invalid
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293558">293558</a>
-[quick assist] &quot;Invert if statement&quot; fails when comment follows
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=182459">182459</a>
-[compiler] Inconsistent error range for unresolved field
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=192233">192233</a>
-[AST] CompilationUnit.rewrite() removes whitespace between return type and method name
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306073">306073</a>
-ASTRewrite Javadoc wrongly talks about getTargetSourceRangeComputer
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305001">305001</a>
-Exception occurred in listener of Java element change notification
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305590">305590</a>
-Redundant null check false-positive
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305755">305755</a>
-Remove deprecated API that has been added for 3.6
-
-<a name="v_A40"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M7 - March 16, 2010
-<br>Project org.eclipse.jdt.core v_A40
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A40">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=305371">305371</a>
-[formatter] Unexpected indentation of line comment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305281">305281</a>
-[formatter] Turning off formatting changes comment's formatting
-
-<a name="v_A39"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M6 - March 9, 2010 - 3.6.0 M6
-<br>Project org.eclipse.jdt.core v_A39
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A39">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=289057">289057</a>
-Java Content Assist taking too long
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303830">303830</a>
-&quot;X cannot be resolved or is not a field&quot; erroneously reported
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235658">235658</a>
-Valid identifier unrecognized.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304841">304841</a>
-[search] NPE in IndexSelector.initializeIndexLocations
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295866">295866</a>
-FormalParameter in JDT DOM/AST documentation
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304817">304817</a>
-Review documentation of ASTParser class
-
-<a name="v_A38"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M6 - March 5, 2010
-<br>Project org.eclipse.jdt.core v_A38
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A38">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>
-Added two new preferences to allow to disable the formatter in a section of the code.
-These two preference define respectively the tag which disables the formatting
-and the tag which re-enable it.
-<p>
-These new preferences are controlled with the options:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_DISABLING_TAG</code>
-<code>DefaultCodeFormatterConstants.FORMATTER_ENABLING_TAG</code>
-<pre>
-/**
- * FORMATTER / Option to define the tag to put in a comment to disable the formatting.
- * See the {@link #FORMATTER_ENABLING_TAG} option to re-enable it.
- *     - option id:         "org.eclipse.jdt.core.formatter.disabling_tag"
- *     - possible values:   String, with constraints mentioned below
- *     - default:           &quot;&quot;
- * 
- * Note that:
- * 
- * 1. The tag name will be trimmed. Hence if it does contain white spaces
- *    at the beginning or at the end, they will not be taken into account while
- *    searching for the tag in the comments
- * 2. If a tag is starting with a letter or digit, then it cannot be leaded by
- *    another letter or digit to be recognized
- *    (<b><i>"ToDisableFormatter"</i></b> will not be recognized as a disabling tag
- *    <b><i>"DisableFormatter"</i></b>, but <b><i>"Re:DisableFormatter"</i></b>
- *    will be detected for either tag <b><i>"DisableFormatter"</i></b> or
- *    <b><i>":DisableFormatter"</i></b>).
- *    Respectively, a tag ending with a letter or digit cannot be followed by a letter
- *    or digit to be recognized (<b><i>"DisableFormatter1"</i></b> will not be
- *    recognized as a disabling tag <b><i>"DisableFormatter"</i></b>, but
- *    <b><i>"DisableFormatter:1"</i></b> will be detected either for tag
- *    <b><i>"DisableFormatter"</i></b> or <b><i>"DisableFormatter:"</i></b>)
- * 3. As soon as the formatter encounters the defined disabling tag, it stops to
- *    format the code from the beginning of the comment including this tag. If it
- *    was already disabled, the tag has no special effect.
- *    For example, the second defined enabling tag &quot;<b>disable-formatter</b>&quot;
- *    in the following snippet is not necessary as the formatter was already disabled
- *    since the first one:
- *     class X {
- *     // disable-formatter
- *     void foo1() {}
- *     // disable-formatter
- *     void foo2() {}
- *     void bar1() {}
- *     void bar2() {}
- *     }
- *
- * 4. If no enabling tag is found by the formatter after the disabling tag, then
- *    the end of the snippet won't be formatted.
- *    For example, when a disabling tag is put at the beginning of the code, then
- *    the entire content of a compilation unit is not formatted:
- *     // disable-formatter
- *     class X {
- *     void foo1() {}
- *     void foo2() {}
- *     void bar1() {}
- *     void bar2() {}
- *     }
- * 
- * 5. If a mix of disabling and enabling tags is done in the same comment, then
- *    the formatter will only take into account the last encountered tag in the
- *    comment.
- *    For example, in the following snippet, the formatter will be disabled after
- *    the comment:
- *     class X {
- *     /*
- *     &nbsp;* This is a comment with a mix of disabling and enabling tags:
- *     &nbsp;*  - <b>disable-formatter</b>
- *     &nbsp;*  - <b>enable-formatter</b>
- *     &nbsp;*  - <b>disable-formatter</b>
- *     &nbsp;* The formatter will stop to format from the beginning of this comment...
- *     &nbsp;*/
- *     void foo() {}
- *     void bar() {}
- *     }
- * 
- * 6. The tag cannot include newline character (i.e. '\n') but it can have white spaces.
- *    E.g. "<b>format: off</b>" is a valid disabling tag
- *    In the future, newlines may be used to support multiple disabling tags.
- * 
- * @since 3.6
- */
-
-/**
- * FORMATTER / Option to define the tag to put in a comment to re-enable the
- * formatting after it has been disabled (see {@link #FORMATTER_DISABLING_TAG})
- *     - option id:         "org.eclipse.jdt.core.formatter.enabling_tag"
- *     - possible values:   String, with constraints mentioned below
- *     - default:           &quot;&quot;
- * 
- * Note that:
- * 
- * 1. The tag name will be trimmed. Hence if it does contain white spaces
- *    at the beginning or at the end, they will not be taken into account while
- *    searching for the tag in the comments
- * 2. If a tag is starting with a letter or digit, then it cannot be leaded by
- *    another letter or digit to be recognized
- *    (<b>"ReEnableFormatter"</b> will not be recognized as an enabling tag
- *    <b><i>"EnableFormatter"</i></b>, but <b><i>"Re:EnableFormatter"</i></b>
- *    will be detected for either tag <b><i>"EnableFormatter"</i></b> or
- *    <b><i>":EnableFormatter"</i></b>).
- *    Respectively, a tag ending with a letter or digit cannot be followed by a letter
- *    or digit to be recognized (<b><i>"EnableFormatter1"</i></b> will not be
- *    recognized as an enabling tag <b><i>"EnableFormatter"</i></b>, but
- *    <b><i>"EnableFormatter:1"</i></b> will be detected either for tag
- *    <b><i>"EnableFormatter"</i></b> or <b><i>"EnableFormatter:"</i></b>)
- * 3. As soon as the formatter encounters the defined enabling tag, it re-starts
- *    to format the code just after the comment including this tag. If it was already
- *    active, i.e. already re-enabled or never disabled, the tag has no special effect.
- *    For example, the defined enabling tag &quot;<b>enable-formatter</b>&quot;
- *    in the following snippet is not necessary as the formatter has never been
- *    disabled:
- *     class X {
- *     void foo1() {}
- *     void foo2() {}
- *     // enable-formatter
- *     void bar1() {}
- *     void bar2() {}
- *     }
- * 
- *    Or, in the following other snippet, the second enabling tag is not necessary as
- *    the formatting will have been re-enabled by the first one:
- *     class X {
- *     // disable-formatter
- *     void foo1() {}
- *     void foo2() {}
- *     // enable-formatter
- *     void bar1() {}
- *     // enable-formatter
- *     void bar2() {}
- *     }
- * 
- * 4. If a mix of disabling and enabling tags is done in the same comment, then
- *    the formatter will only take into account the last encountered tag in the
- *    comment.
- *    For example, in the following snippet, the formatter will be re-enabled after
- *    the comment:
- *     // disable-formatter
- *     class X {
- *     /*
- *     &nbsp;* This is a comment with a mix of disabling and enabling tags:
- *     &nbsp;*  - <b>enable-formatter</b>
- *     &nbsp;*  - <b>disable-formatter</b>
- *     &nbsp;*  - <b>enable-formatter</b>
- *     &nbsp;* The formatter will restart to format after this comment...
- *     &nbsp;*/
- *     void foo() {}
- *     void bar() {}
- *     }
- * 
- * 5. The tag cannot include newline character (i.e. '\n') but it can have white spaces.
- *    E.g. "<b>format: on</b>" is a valid enabling tag
- *    In the future, newlines may be used to support multiple enabling tags.
- * 
- * @since 3.6
- */
-</pre>
-<p>For example, the following snippet:</p>
-<pre>
-public class Test {
-/* disable-formatter */
-void     foo(    )      {	
-				//      unformatted       area  	  
-}
-/* enable-formatter */
-void     bar(    )      {	
-				//      formatted       area  	  
-}
-}
-</pre>
-formatted with disabling tags = &quot;disable-formatter&quot; and enabling tags
-= &quot;enable-formatter&quot; produces the following output:
-<pre>
-public class Test {
-
-/* disable-formatter *	
-void     foo(    )      {
-				//      unformatted       area  	  
-}
-/* enable-formatter *
-	void bar() {
-		// formatted area
-	}
-}
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=27079">27079</a> for more details.
-</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=129804">129804</a>
-[dom] Local variable bindings from ASTParser#createASTs(.., String[], .., ..) have no declaring method
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304705">304705</a>
-[formatter] Unexpected indentation of wrapped line comments when 'Never indent line comment on first column' preference is checked
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304656">304656</a>
-StringIndexOutOfBoundsException when using JDT dom methods to process sourcefile
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304506">304506</a>
-Task descriptions always have a space after the tag
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304081">304081</a>
-IJavaProject#isOnClasspath(IJavaElement) returns false for type from referenced JAR
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304122">304122</a>
-TypeBindings.getAnnotations() breaks interface
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304416">304416</a>
-VerifyError after compiling without preserve all locals
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304529">304529</a>
-[formatter] NPE when either the disabling or the enabling tag is not defined
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=27079">27079</a>
-Tags for disabling/enabling code formatter (feature)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304316">304316</a>
-NPE when javadoc URL is invalid
-
-<a name="v_A37"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M6 - March 2, 2010
-<br>Project org.eclipse.jdt.core v_A37
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A37">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>Added new configurable option to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295551">295551</a>:<br>
-<pre>
-/**
- * Compiler option ID: Further Determining the Effect of @SuppressWarnings if also
- * COMPILER_PB_SUPPRESS_WARNINGS is enabled.
- * When enabled, the @SuppressWarnings annotation can additionally be used to suppress 
- * optional compiler diagnostics that have been configured as ERROR.
- * When disabled, all @SuppressWarnings annotations only affects warnings.
- *
- * Option id: "org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors"
- * Possible values: { "enabled", "disabled" }
- * Default: "disabled"
- * 
- * @since 3.6
- * @category CompilerOptionID
- */
-public static final String COMPILER_PB_SUPPRESS_OPTIONAL_ERRORS = PLUGIN_ID + ".compiler.problem.suppressOptionalErrors";
+    /**
+     * Returns the Java type root in which this local variable is declared.
+     *
+     * This is a handle-only method.
+     *
+     * @return the Java type root in which this local variable is declared
+     * @since 3.7
+     */
+    ITypeRoot getTypeRoot();
 </pre>
 </li>
-<li>
-Added a new formatter preferences to align method declaration.
-<p>
-This new preference is controlled with the option:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_METHOD_DECLARATION</code>
+<li>Adding missing API method on org.eclipse.jdt.core.ITypeParameter (see details in <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=48420">bug 48420</a>):
 <pre>
-/**
- * FORMATTER / Option for alignment of method declaration
- *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_method_declaration"
- *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
- *     - default:           createAlignmentValue(false, WRAP_NO_SPLIT, INDENT_DEFAULT)
- * 
- * @see #createAlignmentValue(boolean, int, int)
- * @since 3.6
- */
-</pre>
-<p>For example, the following snippet:</p>
-<pre>
-public class Test {
-public final synchronized java.lang.String a_method_which_has_a_very_long_name() {
-return null;
-}
-}
-</pre>
-formatted with this preference activated as 'Wrap only when necessary', will
-produce the following output:
-<pre>
-public class Test {
-	public final synchronized java.lang.String
-			a_method_which_has_a_very_long_name() {
-		return null;
-	}
-}
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284789">284789</a> for more details.
-</li>
-<li>New API to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=246594">246594</a>. See the bug for details.
-<pre>
-org.eclipse.jdt.core.ITypeParameter
-	/**
-	 * Returns the signatures for this type parameter's bounds. The type parameter may have 
-	 * been declared as part of a type or a method. The signatures represent only the individual 
-	 * bounds and do not include the type variable name or the <code>extends</code> keyword.  
-	 * The signatures may be either unresolved (for source types) or resolved (for binary types). 
-	 * See {@link Signature} for details.
-	 * 
-	 * @return the signatures for the bounds of this formal type parameter
-	 * @throws JavaModelException
-	 *             if this element does not exist or if an exception occurs while accessing its corresponding resource.
-	 * @see Signature
-	 * @since 3.6
-	 */
-	String[] getBoundsSignatures() throws JavaModelException;
-</pre>
-</li>
-<li>
-Added a new formatter preference to enable or disable the formatting of line
-comments that start on the first column.<br>
-Note that the indentation of line comments will also be disabled when activating
-this option, as otherwise the formatter could not produce stable outputs...
-<p>
-The default is to format these comments to have a backward compatible behavior.
-</p><p>
-This new preferences is controlled with the options:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN</code>
-<pre>
-/**
- * FORMATTER / Option to format line comments that start on the first column
- *     - option id:         "org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column"
- *     - possible values:   { TRUE, FALSE }
- *     - default:           TRUE
- * 
- * Note that this option is ignored if either the
- * {@link #FORMATTER_COMMENT_FORMAT_LINE_COMMENT} option has been set to
- * {@link #FALSE} or the formatter is created with the mode
- * {@link ToolFactory#M_FORMAT_NEW}.
- * 
- * @see #TRUE
- * @see #FALSE
- * @see ToolFactory#createCodeFormatter(Map, int)
- * @since 3.6
- */
-</pre>
-<p>For example, the following snippet:</p>
-<pre>
-public class X01 {
-//    int	a  =   1;
-//    int	b  =   2;
-}
-</pre>
-will be untouched by the formatter if both options are activated.
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=251133">251133</a> for more details.
-</li>
-<li>New API to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=252431">252431</a>. See the bug for details.
-<pre>
-org.eclipse.jdt.core.IClasspathEntry
-	/**
-	 * Returns the classpath entry that is making a reference to this classpath entry. For entry kinds 
-	 * {@link #CPE_LIBRARY}, the return value is the entry that is representing the JAR that includes 
-	 * <code>this</code> in the MANIFEST.MF file's Class-Path section. For entry kinds other than 
-	 * {@link #CPE_LIBRARY}, this returns <code>null</code>. For those entries that are on the raw classpath already, 
-	 * this returns <code>null</code>.
-	 *
-	 * It is possible that multiple library entries refer to the same entry
-	 * via the MANIFEST.MF file. In those cases, this method returns the first classpath entry 
-	 * that appears in the raw classpath. However, this does not mean that the other referencing 
-	 * entries do not relate to their referenced entries. 
-	 * See {@link JavaCore#getReferencedClasspathEntries(IClasspathEntry, IJavaProject)} for 
-	 * more details.
-	 * 
-	 * @return the classpath entry that is referencing this entry or <code>null</code> if 
-	 * 		not applicable.
-	 * @since 3.6
-	 */
-	IClasspathEntry getReferencingEntry();
-
-
-org.eclipse.jdt.core.IJavaProject
-	/**
-	 * Works similar to {@link #setRawClasspath(IClasspathEntry[], IPath, IProgressMonitor)} and 
-	 * additionally allows persisting the given array of referenced entries for this project.
-	 * The referenced entries and their attributes are stored in the .classpath file of this 
-	 * project. For details on referenced entries, see 
-	 * {@link JavaCore#getReferencedClasspathEntries(IClasspathEntry, IJavaProject)}
-	 * and {@link IClasspathEntry#getReferencingEntry()}.
-	 * 
-	 * Since the referenced entries are stored in the .classpath file, clients can store additional 
-	 * information that belong to these entries and retrieve them across sessions, though the referenced
-	 * entries themselves may not be present in the raw classpath. By passing a <code>null</code>
-	 * referencedEntries, clients can choose not to modify the already persisted referenced entries,
-	 * which is fully equivalent to {@link #setRawClasspath(IClasspathEntry[], IPath, IProgressMonitor)}.
-	 * If an empty array is passed as referencedEntries, the already persisted referenced entries, 
-	 * if any, will be cleared. 
-	 * 
-	 * If there are duplicates of a referenced entry or if any of the <code>referencedEntries</code> 
-	 * is already present in the raw classpath(<code>entries</code>) those referenced entries will 
-	 * be excluded and not be persisted.
-	 *
-	 * @param entries a list of classpath entries
-	 * @param referencedEntries the list of referenced classpath entries to be persisted
-	 * @param outputLocation the default output location
-	 * @param monitor the given progress monitor
-	 * @exception JavaModelException if the classpath could not be set. Reasons include:
-	 *  	This Java element does not exist (ELEMENT_DOES_NOT_EXIST)
-	 *  	The classpath is being modified during resource change event notification (CORE_EXCEPTION)
-	 *  	The classpath failed the validation check as defined by {@link JavaConventions#validateClasspath(IJavaProject, IClasspathEntry[], IPath)}
-	 * @see IClasspathEntry
-	 * @see #getReferencedClasspathEntries()
-	 * @since 3.6
-	 */
-	void setRawClasspath(IClasspathEntry[] entries, IClasspathEntry[] referencedEntries, IPath outputLocation,
-			IProgressMonitor monitor) throws JavaModelException;
-
-	/**
-	 * Returns the list of referenced classpath entries stored in the .classpath file of <code>this</code> 
-	 * java project. Clients can store the referenced classpath entries using 
-	 * {@link #setRawClasspath(IClasspathEntry[], IClasspathEntry[], IPath, IProgressMonitor)}
-	 * If the client has not stored any referenced entries for this project, an empty array is returned.
-	 *
-	 * @throws JavaModelException
-	 * @return an array of referenced classpath entries stored for this java project or an empty array if none
-	 * 			stored earlier.
-	 * @since 3.6
-	 */
-	IClasspathEntry[] getReferencedClasspathEntries() throws JavaModelException;
-	
-
-org.eclipse.jdt.core.IPackageFragmentRoot
-	/**
-	 * Returns the first resolved classpath entry that corresponds to this package fragment root.
-	 * A resolved classpath entry is said to correspond to a root if the path of the resolved
-	 * entry is equal to the root's path.
-	 * 
-	 * @return the first resolved classpath entry that corresponds to this package fragment root
-	 * @throws JavaModelException if this element does not exist or if an
-	 *		exception occurs while accessing its corresponding resource. 
-	 * @since 3.6
-	 */
-	IClasspathEntry getResolvedClasspathEntry() throws JavaModelException;
-	
-
-org.eclipse.jdt.core.JavaCore
-	/**
-	 * Returns an array of classpath entries that are referenced directly or indirectly 
-	 * by a given classpath entry. For the entry kind {@link IClasspathEntry#CPE_LIBRARY}, 
-	 * the method returns the libraries that are included in the Class-Path section of 
-	 * the MANIFEST.MF file. If a referenced JAR file has further references to other library 
-	 * entries, they are processed recursively and added to the list. For entry kinds other 
-	 * than {@link IClasspathEntry#CPE_LIBRARY}, this method returns an empty array.
-	 *
-	 * If a referenced entry has already been stored 
-	 * in the given project's .classpath, the stored attributes are populated in the corresponding
-	 * referenced entry. For more details on storing referenced entries see
-	 * see {@link IJavaProject#setRawClasspath(IClasspathEntry[], IClasspathEntry[], IPath, 
-	 * IProgressMonitor)}. 
-	 * 
-	 * @param libraryEntry the library entry whose referenced entries are sought 
-	 * @param project project where the persisted referenced entries to be retrieved from
-	 * @return an array of classpath entries that are referenced directly or indirectly by the given entry. 
-	 * 			If not applicable, returns an empty array.
-	 * @since 3.6
-	 */
-	public static IClasspathEntry[] getReferencedClasspathEntries(IClasspathEntry libraryEntry, IJavaProject project);	
+    /**
+     * Returns the Java type root in which this type parameter is declared.
+     *
+     * This is a handle-only method.
+     *
+     * @return the Java type root in which this type parameter is declared
+     * @since 3.7
+     */
+    ITypeRoot getTypeRoot();
 </pre>
 </li>
 </ul>
 
 <h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=252431">252431</a>
-New API is needed to better identify referenced jars in the Class-Path: entry
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=251133">251133</a>
-[formatter] Automatic formatting single line comments is incoherent among tools
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=248897">248897</a>
-[1.5][compiler] Wrong warning 'The local variable 'var' is never read'.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304031">304031</a>
-Unused @SuppressWarnings(..) not flagged when suppressed problem is set to Error
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295551">295551</a>
-Add option to automatically promote all warnings to errors
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303810">303810</a>
-Compact boolean fields on FlowContext
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=251227">251227</a>
-[compiler] Fup of bug 115814, comparing doubles should not be flagged
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=268798">268798</a>
-[1.5][compiler] Eclipse 3.5M5/6 produces new compiler errors with generics
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448">303448</a>
-Wrong code generation optimization when assert condition is false
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303776">303776</a>
-Member types imports are removed too aggressively
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302949">302949</a>
-JavaModelManager hangs accessing the nonChainingJars set
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=246594">246594</a>
-[model] API request: ITypeParameter#getBoundsSignatures() or #getSignature()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=253896">253896</a>
-[compiler][null] wrong &quot;Null comparison always yields false&quot; problem for auto-unboxing
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284789">284789</a>
-[formatter] Does not line-break method declaration exception with parameters
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303480">303480</a>
-[1.5][compiler] CCE: org.eclipse.jdt.internal.compiler.parser.RecoveredBlock cannot be cast to org.eclipse.jdt.internal.compiler.parser.RecoveredType
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324762">324762</a>
+Compiler thinks there is deadcode and removes it!
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478">292478</a>
+Report potentially null across variable assignment
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324748">324748</a>
+JDT core tests have restrictive range on com.ibm.icu
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633">323633</a>
+[1.5][compiler] Reconciler issues mixing 1.4 projects with &amp; 1.5 project with generics.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317046">317046</a>
+Exception during debugging when hover mouse over a field
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=48420">48420</a>
+[API] ILocalVariable and ITypeParameter should provide more methods
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321414">321414</a>
+Synthetic constructors can exceed 255 parameters -&gt; ClassFormatError
 
-<a name="v_A36"></a>
+<a name="v_B10"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M6 - February 23, 2010
-<br>Project org.eclipse.jdt.core v_A36
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A36">cvs</a>).
+Eclipse SDK 3.7M2 - September 7, 2010
+<br>Project org.eclipse.jdt.core v_B10
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B10">cvs</a>).
 <h2>What's new in this drop</h2>
 <ul>
-<li>
-Added a new formatter preferences to align annotation arguments (i.e. element-value pairs).
-<p>
-This new preference is controlled with the option:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ANNOTATION</code>
+<li>Code formatter: 4 new options were added to better handle the addition of
+new lines after annotations.
 <pre>
-/**
- * FORMATTER / Option for alignment of arguments in annotation
- *     - option id:         "org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation"
- *     - possible values:   values returned by <code>createAlignmentValue(boolean, int, int)</code> call
- *     - default:           createAlignmentValue(false, WRAP_NO_SPLIT, INDENT_DEFAULT)
- * 
- * @see #createAlignmentValue(boolean, int, int)
- * @since 3.6
- */
-</pre>
-<p>For example, the following snippet:</p>
-<pre>
-@MyAnnot(value1 = "this is an example", value2 = "of an annotation", value3 = "with several arguments", value4 = "which may need to be wrapped")
-public class Test {
-}
-</pre>
-formatted with this preference activated, will produce the following output
-while using the <code>Eclipse [built-in]</code> profile:
-<pre>
-@MyAnnot(value1 = "this is an example", value2 = "of an annotation",
-		value3 = "with several arguments",
-		value4 = "which may need to be wrapped")
-public class Test {
-}
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282030">282030</a> for more details.
-</li>
-<li>In order to get bindings outside the Eclipse environment, the following methods has been added on the ASTParser class.
-<br>See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=206391">206391</a> for details.<br>
-<pre>
-org.eclipse.jdt.core.dom.ASTParser
-	/**
-	 * Set the environment that can be used when no IJavaProject are available.
-	 * 
-	 * The user has to be sure to include all required types on the classpaths for binary types
-	 * or on the sourcepaths for source types to resolve the given source code.
-	 * All classpath and sourcepath entries are absolute paths.
-	 * If sourcepaths contain units using a specific encoding (not the platform encoding), then the
-	 * given encodings must be set. If the given encodings is set, its length must
-	 * match the length of the sourcepaths parameter or an IllegalArgumentException will be thrown.
-	 * If encodings is not null, the given sourcepathEntries must not be null.
-	 * 
-	 * @param classpathEntries the given classpath entries to be used to resolve bindings
-	 * @param sourcepathEntries the given sourcepath entries to be used to resolve bindings
-	 * @param encodings the encodings of the corresponding sourcepath entries or null if the platform encoding
-	 * can be used.
-	 * @param includeRunningVMBootclasspath true if the bootclasspath of the running VM must be prepended to the
-	 * given classpath and false if the bootclasspath of the running VM should be ignored.
-	 * @throws IllegalArgumentException if the size of the given encodings is not equals to the size of the given
-	 * sourcepathEntries
-	 * @since 3.6
-	 */
-	public void setEnvironment(String[] classpathEntries, String[] sourcepathEntries, String[] encodings, boolean includeRunningVMBootclasspath);
-	
-	/**
-	 * Creates ASTs for a batch of compilation units. When bindings are being resolved, processing a
-	 * batch of compilation units is more efficient because much of the work involved in resolving 
-	 * bindings can be shared. 
-	 *
-	 * When bindings are being resolved, all compilation units are resolved 
-	 * using the same environment, which must be set beforehand with 
-	 * {@link #setEnvironment(String[], String[], String[], boolean) setEnvironment}.
-	 * The compilation units are processed one at a time in no specified order. 
-	 * For each of the compilation units in turn,
-	 *  - {@link ASTParser#createAST(IProgressMonitor) ASTParser.createAST} is called to parse it 
-	 *           and create a corresponding AST. The calls to {@link ASTParser#createAST(IProgressMonitor) ASTParser.createAST} 
-	 *           all employ the same settings.</li>
-	 *  - {@link FileASTRequestor#acceptAST(String, CompilationUnit) FileASTRequestor.acceptAST} is called passing
-	 *           the compilation unit path and the corresponding AST to <code>requestor</code>. The compilation unit path is the same
-	 *           path that is passed into the given <code>sourceFilePaths</code> parameter.
-	 *
-	 * Note only ASTs from the given compilation units are reported
-	 * to the requestor. If additional compilation units are required to
-	 * resolve the original ones, the corresponding ASTs are <b>not</b>
-	 * reported to the requestor.
-	 * 
-	 * Note also the following parser parameters are used, regardless of what
-	 * may have been specified:
-	 *  - The {@linkplain #setKind(int) parser kind} is <code>K_COMPILATION_UNIT</code>
-	 *  - The {@linkplain #setSourceRange(int,int) source range} is <code>(0, -1)</code>
-	 *  - The {@linkplain #setFocalPosition(int) focal position} is not set
-	 *
-	 * The <code>bindingKeys</code> parameter specifies bindings keys
-	 * ({@link IBinding#getKey()}) that are to be looked up. These keys may
-	 * be for elements either inside or outside the set of compilation
-	 * units being processed. When bindings are being resolved,
-	 * the keys and corresponding bindings (or <code>null</code> if none) are
-	 * passed to {@link FileASTRequestor#acceptBinding(String, IBinding) FileASTRequestor.acceptBinding}. Note that binding keys
-	 * for elements outside the set of compilation units being processed are looked up
-	 * after all {@link FileASTRequestor#acceptAST(String, CompilationUnit) ASTRequestor.acceptAST}
-	 * callbacks have been made.
-	 * Binding keys for elements inside the set of compilation units being processed
-	 * are looked up and reported right after the corresponding
-	 * {@link FileASTRequestor#acceptAST(String, CompilationUnit) FileASTRequestor.acceptAST} callback has been made.
-	 * No {@link FileASTRequestor#acceptBinding(String, IBinding) FileASTRequestor.acceptBinding} callbacks are made unless
-	 * bindings are being resolved.
-	 *
-	 * A successful call to this method returns all settings to their
-	 * default values so the object is ready to be reused.
-	 * 
-	 * The given <code>encodings</code> are used to properly parse the given source units. If the platform encoding is sufficient,
-	 * then the given encodings can be set to <code>null</code>.
-	 *
-	 * @param sourceFilePaths the compilation units to create ASTs for
-	 * @param encodings the given encoding for the source units
-	 * @param bindingKeys the binding keys to create bindings for
-	 * @param requestor the AST requestor that collects abstract syntax trees and bindings
-	 * @param monitor the progress monitor used to report progress and request cancellation,
-	 *   or <code>null</code> if none
-	 * @exception IllegalStateException if the settings provided
-	 * are insufficient, contradictory, or otherwise unsupported
-	 * @since 3.6
-	 */
-	 public void createASTs(String[] sourceFilePaths, String[] encodings, String[] bindingKeys, FileASTRequestor requestor, IProgressMonitor monitor)
-</pre>
-</li>
-<li>
-Added two new formatter preferences to condense block and javadoc comments.
-<p>
-These new preferences are controlled respectively with the options:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_COMMENT_NEW_LINES_AT_BLOCK_BOUNDARIES</code><br>
-<code>DefaultCodeFormatterConstants.FORMATTER_COMMENT_NEW_LINES_AT_JAVADOC_BOUNDARIES</code>
-<pre>
-/**
- * FORMATTER / Option to control whether block comments will have new lines at boundaries
- *     - option id:         "org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries"
- *     - possible values:   { TRUE, FALSE }
- *     - default:           TRUE
- * 
- * @see #TRUE
- * @see #FALSE
- * @since 3.6
- */
-
-/**
- * FORMATTER / Option to control whether javadoc comments will have new lines at boundaries
- *     - option id:         "org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries"
- *     - possible values:   { TRUE, FALSE }
- *     - default:           TRUE
- * 
- * @see #TRUE
- * @see #FALSE
- * @since 3.6
- */
- </pre>
-<p>For example, the following snippet:</p>
-<pre>
-public class X {
-	/*
-	 * This block comment after formatting will no longer use a new line
-	 * at the beginning and at the end of the comment...
-	 */
-	void foo() {
-	}
-	/**
-	 * This javadoc comment after formatting will no longer use a new line
-	 * at the beginning and at the end of the comment...
-	 */
-	void bar() {
-	}
-}
-</pre>
-formatted with both the options set to FALSE, will produce the following output:
-<pre>
-public class X {
-	/* This block comment after formatting will no longer use a new line at the
-	 * beginning and at the end of the comment... */
-	void foo() {
-	}
-
-	/** This javadoc comment after formatting will no longer use a new line at
-	 * the beginning and at the end of the comment... */
-	void bar() {
-	}
-}
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=270209">270209</a> for more details.
-</li>
-<li>
-The <code>CodeFormatter.F_INCLUDE_COMMENT</code> flag now works for all kind
-of snippet while using the formatter.<br>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=236406">236406</a> for more details.
-</li>
-<li>
-Added a new formatter preferences to insert a new line after a label.
-<p>
-This new preference is controlled with the option:</p>
-<code>DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL</code>
-<pre>
-/**
- * FORMATTER / Option to insert a new line after a label
- *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_label"
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_FIELD
+ * FORMATTER / Option to insert a new line after an annotation on a field declaration
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field"
  *     - possible values:   { INSERT, DO_NOT_INSERT }
- *     - default:           DO_NOT_INSERT
- *
- * @see JavaCore#INSERT
- * @see JavaCore#DO_NOT_INSERT
- * @since 3.6
- */
-</pre>
-<p>For example, the following snippet:</p>
-<pre>
-public class X {
-	void foo() {
-		LABEL:for (int i = 0; i &lt; 10; i++) {
-		}
-	}
-}
-</pre>
-formatted with this preference activated, will produce the following output:
-<pre>
-public class X {
-	void foo() {
-		LABEL:
-		for (int i = 0; i &lt; 10; i++) {
-		}
-	}
-}
-</pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=150741">150741</a> for more details.
-</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298362">298362</a>
-[1.5][compiler] Compiler returns java.lang.Object instead of generic type T when javac returns T
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281655">281655</a>
-[formatter] &quot;Never join lines&quot; does not work for annotations.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282030">282030</a>
-[formatter] Java annotation formatting
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=270209">270209</a>
-[format] Condensed block comment formatting
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=236406">236406</a>
-[formatter] The comments flags should work for all kinds of snippet
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294360">294360</a>
-Duplicate entries in Classpath Resolution when importing dependencies from parent project
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=206391">206391</a>
-[DOM] Binding Resolutions for projects outside of Eclipse workspace
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=150409">150409</a>
-[compiler] AST does not expose method bindings for non-visible inherited field
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302358">302358</a>
-Compiler finds wrong method for method invocation with generics
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302919">302919</a>
-misreported cast Error when mixing generic and raw class in nested class
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=150741">150741</a>
-[formatter] Add  option: &quot;add new line after label&quot;
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287939">287939</a>
-[code assist] The instanceof and the auto cast feature should also work for an assignment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=303108">303108</a>
-[import rewrite] ImportRewrite#removeImport(String) does not work with setUseContextToFilterImplicitImports(true)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295619">295619</a>
-Test failure caused by a timing issue in M20091118-0800
-
-<a name="v_A35"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M6 - February 16, 2010
-<br>Project org.eclipse.jdt.core v_A35
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A35">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>In order to fix bugs <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235253">235253</a> and
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=194358">194358</a>, a new API was added to preserve the existing pre-3.6 behavior for existing clients:<br>
-<pre>
-	/**
-	 * Sets whether a context should be used to properly filter implicit imports.
-	 *
-	 * By default, the option is disabled to preserve pre-3.6 behavior.
-	 *
-	 *
-	 * When this option is set, the context passed to the addImport*(...) methods is used to determine
-	 * whether an import can be filtered because the type is implicitly visible. Note that too many imports
-	 * may be kept if this option is set and addImport*(...) methods are called without a context.
-	 *
-	 * 
-	 * @param useContextToFilterImplicitImports the given setting
-	 * 
-	 * @see #setFilterImplicitImports(boolean)
-	 * @since 3.6
-	 */
-	public void setUseContextToFilterImplicitImports(boolean useContextToFilterImplicitImports);
-</pre>
-</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302455">302455</a>
-java.lang.ClassCastException in secondary types removal
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=102279">102279</a>
-[search] method reference performance depends on method name
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=236814">236814</a>
-[jsr199] EclipseCompiler#getTask does not respect its contract when its first argument is null
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302552">302552</a>
-[formatter] Formatting qualified invocations can be broken when the Line Wrapping policy forces element to be on a new line
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302587">302587</a>
-Encoding/decoding of problem arguments in Marker fails if argument contains #
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=301438">301438</a>
-Eclipse hangs when attempting to refactor using the &quot;change method signature&quot;
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=260381">260381</a>
-[formatter] Javadoc formatter breaks {@code ...} tags.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302446">302446</a>
-[compiler] Regression in if statement flow analysis related to null checks
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=194358">194358</a>
-[import rewrite] Organize Imports produces wrong order of imports
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235253">235253</a>
-[organize imports] Organize imports removes needed import statement.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=302379">302379</a>
-[search] JavaSearchTests.testZIPArchive2() test failed in I20100209-0800
-
-<a name="v_A34"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M6 - February 9, 2010
-<br>Project org.eclipse.jdt.core v_A34
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A34">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=302123">302123</a>
-[formatter] AssertionFailedException occurs while formatting a source containing the specific javadoc comment /** ***/
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300379">300379</a>
-[formatter] Fup of bug 287833
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=250056">250056</a>
-[compiler][null] Another assert and &quot;Redundant null check&quot;
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=301683">301683</a>
-Annotations are broken when native methods are present in a class
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300734">300734</a>
-Extract temp misses duplicate occurrence.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289560">289560</a>
-Eclipse hangs after modifying user libraries
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=301562">301562</a>
-[JSR269] Error in EclipseFileManager.collectAllMatchingFiles
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298637">298637</a>
-Could not retrieve declared methods (NPE in ParameterizedTypeBinding.resolve)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294057">294057</a>
-[1.5][compiler] Imports not resolved correctly with generics and inner interfaces
-
-<a name="v_A33"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M6 - February 2, 2010
-<br>Project org.eclipse.jdt.core v_A33
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A33">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=300136">300136</a>
-classpathentry OPTIONAL attribute not honored for var entries
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300723">300723</a>
-Fup of bug 235783
-
-<a name="v_A32a"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M5 - January 21, 2010 - 3.6.0 M5
-<br>Project org.eclipse.jdt.core v_A32a
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A32a">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=300133">300133</a>
-[1.5][compiler] Local classes inside enum constants generate default constructor without implicit constructor call
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300440">300440</a>
-icu dependency needs to be udpated
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=299900">299900</a>
-[null]Missing potential null warnings for variable on the right of an OR conditional expression
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293917">293917</a>
-Invalid 'potential null access' warning reports
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=252379">252379</a>
-Organize imports deletes needed static import.
-
-<a name="v_A31"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M5 - January 18, 2010
-<br>Project org.eclipse.jdt.core v_A31
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A31">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>New API to fix bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295894">295894</a>. See the bug for details.
-<pre>
-/**
- * Returns a Java search scope limited to the hierarchy of the given type and to a given project.
- * The Java elements resulting from a search with this scope will be types in this hierarchy.
- *
- * Unlike the createHierarchyScope methods, this method creates strict
- * scopes that only contain types that actually span the hierarchy of the focus
- * type, but do not include additional enclosing or member types.
- *
- *
- * By default, hierarchy scopes include all direct and indirect supertypes and subtypes of the
- * focus type. This method, however, allows to restrict the hierarchy to true subtypes,
- * not including supertypes. Also inclusion of the focus type itself is controled by a parameter. 
- *
+ *     - default:           INSERT
  * 
- * @param project the project to which to constrain the search, or null if
- *        search should consider all types in the workspace 
- * @param type the focus of the hierarchy scope
- * @param onlySubtypes if true only subtypes of type are considered
- * @param includeFocusType if true the focus type type is included in the resulting scope, 
- * 		  otherwise it is excluded
- * @param owner the owner of working copies that take precedence over original compilation units, 
- *        or null if the primary working copy owner should be used
- * @return a new hierarchy scope
- * @exception JavaModelException if the hierarchy could not be computed on the given type
- * @since 3.6
- */
-public static IJavaSearchScope createStrictHierarchyScope(IJavaProject project, IType type, boolean onlySubtypes, boolean includeFocusType, WorkingCopyOwner owner) throws JavaModelException;
-</pre>
-</li>
-<li>New API added to report a compiler warning when object allocations are unused:
-<pre>
-org.eclipse.jdt.core.compiler.IProblem.UnusedObjectAllocation
-
-/**
- * Compiler option ID: Reporting Allocation of an Unused Object.
- * When enabled, the compiler will issue an error or a warning if an object is allocated but never used,
- * neither by holding a reference nor by invoking one of the object's methods.
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_METHOD
+ * FORMATTER / Option to insert a new line after an annotation on a method declaration
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method"
+ *     - possible values:   { INSERT, DO_NOT_INSERT }
+ *     - default:           INSERT
  *
- * Option id:"org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation"
- * Possible values:{ "error", "warning", "ignore" }
- * Default:"ignore"
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE
+ * FORMATTER / Option to insert a new line after an annotation on a package declaration
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package"
+ *     - possible values:   { INSERT, DO_NOT_INSERT }
+ *     - default:           INSERT
  *
- * @since 3.6
- * @category CompilerOptionID
- */
-public static final String COMPILER_PB_UNUSED_OBJECT_ALLOCATION = PLUGIN_ID + ".compiler.problem.unusedObjectAllocation";
+ * FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE
+ * FORMATTER / Option to insert a new line after an annotation on a type declaration
+ *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type"
+ *     - possible values:   { INSERT, DO_NOT_INSERT }
+ *     - default:           INSERT
 </pre>
+The addition of new lines after annotations has been discussed in <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=308000">bug 308000</a><br>
+Also note that previously available code formatter constant FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER has been deprecated.<br>
+All new options must be enabled to activate old strategy.
 </li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=245007">245007</a>
-[compiler] Should not completely ignore anonymous type with missing super type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295894">295894</a>
-[search] Search shows focus type implementation for nested types even though the scope is restricted to subtypes.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=236385">236385</a>
-[compiler] Warn for potential programming problem if an object is created but not used
-
-<a name="v_A30"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M5 - January 12, 2010
-<br>Project org.eclipse.jdt.core v_A30
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A30">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>New API added to expose the reconcile flags used in the reconcile context:
+<li>
+The previously added new APIs:
+<blockquote>
+<code>org.eclipse.jdt.core.IImportDeclaration#getNameRange()</code>,<br>
+<code>org.eclipse.jdt.core.IPackageDeclaration#getNameRange()</code>
+</blockquote>
+have been moved to the org.eclipse.jdt.core.ISourceReference interface. See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321764">321764</a> for details:
 <pre>
 /**
- * Returns the reconcile flag of this context. This flag is a bitwise value of the constant defined
- * in ICompilationUnit.
+ * Returns the name range associated with this element.
+ * 
+ * If the element is an IMember, it returns
+ * the source range of this member's simple name,
+ * or null if this member does not have a name
+ * (for example, an initializer), or if this member does not have
+ * associated source code (for example, a binary type).
+ * 
+ * If this element is an IImportDeclaration, the source range
+ * of this import declaration's name, or null if this import
+ * declaration does not have associated source code (for example, a binary type).
+ * The source range for the name includes the trailing '*' if the call to
+ * IImportDeclaration#isOnDemand() returns true.
  *
- * @return the reconcile flag of this context
- * @since 3.6
+ * If this element is an IPackageDeclaration, the source range of
+ * this package declaration's name, or null if this package 
+ * declaration does not have associated source code (for example, a binary type).
  *
- * @see ICompilationUnit#ENABLE_BINDINGS_RECOVERY
- * @see ICompilationUnit#ENABLE_STATEMENTS_RECOVERY
- * @see ICompilationUnit#IGNORE_METHOD_BODIES
+ * If this element is an IAnnotation, the source range of
+ * this annotation's name, or null if this annotation does not have
+ * associated source code (for example, in a binary type).
+ * 
+ * If this element is an ITypeParameter, the source range of this 
+ * type parameter's name, or null if this type parameter does not have
+ * associated source code (for example, in a binary type).
+ * 
+ * If this element is an ITypeRoot or IImportContainer, it
+ * returns null.
+ *
+ * @return the name range associated with this element, or null if
+ * not available
+ *
+ * @since 3.7
  */
-public int getReconcileFlags();
+ISourceRange getNameRange() throws JavaModelException;
 </pre>
 </li>
 </ul>
 
 <h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=243917">243917</a>
-[compiler] should not warn about unused field when native method present
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296343">296343</a>
-OOM error caused by java indexing referencing classloader from threadLocal
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=130000">130000</a>
-[API] ReconcileContext API: Does getAST3 return AST with bindings?
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298238">298238</a>
-Unresolved import in superclass causes 'Cannot reduce the visibility of the inherited method' in subclass
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322979">322979</a>
+[search] use of IJavaSearchConstants.IMPLEMENTORS yields surprising results
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937">316937</a>
+JavaElement.getElementInfo(..) throws JavaModelException when trying to get info for an inner class in an external jar
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322531">322531</a>
+[1.5][Generics] eclipse compiles code rejected by javac with incomparable types error.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308000">308000</a>
+[formatter] Formatter is missing options regarding Annotation Newlines
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321276">321276</a>
+JDT core apis dont recognize InnerClass constructor inside .class files
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=252556">252556</a>
+[formatter] Spaces removed before formatted region of a compilation unit.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=323785">323785</a>
+[builder] NPE when adding 'package-info.java' to default package
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321358">321358</a>
+NPE refreshing external folders
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322596">322596</a>
+[DOM] ASTNode APIs should specify types of property descriptors
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324109">324109</a>
+[search] Java search shows incorrect results as accurate matches
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=324154">324154</a>
+NPE in FlowContext while building
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125">133125</a>
+[compiler][null] need to report the null status of expressions and analyze them simultaneously
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321695">321695</a>
+Test added for bug 319425 doesn't detect the bug
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=258905">258905</a>
+making java.lang.AssertionError accessible thru resolveWellKnownType method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321764">321764</a>
+Add getNameRange() to ISourceReference
 
-<a name="v_A29a"></a>
+<a name="v_B09"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M5 - January 5, 2010
-<br>Project org.eclipse.jdt.core v_A29a
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A29a">cvs</a>).
+Eclipse SDK 3.7M2 - August 31, 2010 - 3.7.0 M2
+<br>Project org.eclipse.jdt.core v_B09
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B09">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=293861">293861</a>
-Problem with refactoring when existing jar with invalid package names
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=264112">264112</a>
-[Formatter] Wrap when necessary too aggressive on short qualifiers
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298250">298250</a>
-[1.6][compiler] NegativeArraySizeException in StackMapFrame.duplicate
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296998">296998</a>
-Unused imports should not prevent execution
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=298243">298243</a>
-[formatter] Removing empty lines between import groups
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=297546">297546</a>
-[formatter] Formatter removes blank after @see if reference is wrapped
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235781">235781</a>
-[compiler] difference to javac in definite unassignment analysis involving an exception within a constructor
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235783">235783</a>
-[eval] CodeSnippetParser and some 'CodeSnippet*' ast node does not seem up to date
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=311578">311578</a>
+[formatter] Enable/disable tag detection should include comment start/end tokens
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320618">320618</a>
+inconsistent initialization of classpath container backed by external class folder
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=323693">323693</a>
+[1.5][compiler] Compiler fails to diagnose name clash
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=323558">323558</a>
+Tests test0307a and test0307e under BatchCompilerTest failing
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=308402">308402</a>
+[index] PatternSearchJob ignores participant index entries
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264">317264</a>
+[search] Refactoring is impossible with commons.lang added to project
 
-<a name="v_A28"></a>
+<a name="v_B08"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M5 - December 14, 2009
-<br>Project org.eclipse.jdt.core v_A28
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A28">cvs</a>).
+Eclipse SDK 3.7M1 - August 24, 2010
+<br>Project org.eclipse.jdt.core v_B08
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B08">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=196714">196714</a>
-[comment] InvalidInputException prevents the AbstractCommentMapper to retrieve tag element
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=297757">297757</a>
-Cannot get bindings for IType corresponding to parameterized anonymous type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=255640">255640</a>
-[spec] Methods Signature.toCharArray(..) have unclear precondition
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=262898">262898</a>
-BufferChangedEvent must not have @noinstantiate
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=181682">181682</a>
-JavaConventions.validateJavaTypeName should list valid constants
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=108784">108784</a>
-SourceMapper doesn't find name range of inner class constructors
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926">321926</a>
+Erroneously deems null check conditional branch to be dead code, and produces incorrect bytecode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320170">320170</a>
+[compiler] [null] Whitebox issues in null analysis
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259">305259</a>
+Strange error when referencing code produced with jsr14 target
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321115">321115</a>
+Compiler is not case sensitive with package names
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310427">310427</a>
+[content assist] FUP of 236306: Variable proposed before definition.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320911">320911</a>
+Not all redundant superinterface problems reported
 
-<a name="v_A27"></a>
+<a name="v_B07"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - December 8, 2009 - 3.6.0 M4
-<br>Project org.eclipse.jdt.core v_A27
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A27">cvs</a>).
+Eclipse SDK 3.7M1 - August 17, 2010
+<br>Project org.eclipse.jdt.core v_B07
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B07">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=297225">297225</a>
-[formatter] Indentation may be still wrong in certain circumstances after formatting
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293697">293697</a>
-JavaSearchBugTests.testBug286379c is failing randomly
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319201">319201</a>
+[null] no warning when unboxing SingleNameReference causes NPE
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322154">322154</a>
+Compiler bug that does not occur in Galileo 3.5.2
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320754">320754</a>
+[formatter] formatter:off/on tags does not work correctly
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=322001">322001</a>
+[1.5][compiler] Name Clash error occurs
 
-<a name="v_A26"></a>
+<a name="v_B06"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - December 7, 2009
-<br>Project org.eclipse.jdt.core v_A26
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A26">cvs</a>).
+Eclipse SDK 3.7M1 - August 10, 2010
+<br>Project org.eclipse.jdt.core v_B06
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B06">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=297045">297045</a>
-Weird tests failures in N20091204-2000 and N20091205-2000 builds
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293300">293300</a>
-[formatter] The formatter is still unstable in certain circumstances
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320167">320167</a>
+Auto-Activation works only once
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320809">320809</a>
+ArrayIndexOutOfBoundsException in IndexManager.writeSavedIndexNamesFile - concurrency issue?
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=321085">321085</a>
+Enhanced for loops need to implement type safety checks on array initializers
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319626">319626</a>
+Preferences-&gt;Java Compiler-&gt; Errors/Warnings -&gt; Undocumented Empty Block
 
-<a name="v_A25"></a>
+<a name="v_B05"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - December 4, 2009
-<br>Project org.eclipse.jdt.core v_A25
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A25">cvs</a>).
+Eclipse SDK 3.7M1 - July 30, 2010 - 3.7.0 M1
+<br>Project org.eclipse.jdt.core v_B05
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B05">cvs</a>).
 <h2>What's new in this drop</h2>
 <ul>
-<li>Match result can now report the access rules through a new API added on <code>TypeNameMatch</code>:
+<li>
+New API added to be able to retrieve the name range for <code>org.eclipse.jdt.core.IImportDeclaration</code>:
 <pre>
 /**
- * Returns the accessibility of the type name match
+ * Returns the source range of this import declaration's name,
+ * or null if this import declaration does not have
+ * associated source code (for example, a binary type).
+ * 
+ * The source range for the name includes the trailing '*' if the call to
+ * isOnDemand() returns true.
+ * 
  *
- * @see IAccessRule
- *
- * @return the accessibility of the type name which may be
- * 		{@link IAccessRule#K_ACCESSIBLE}, {@link IAccessRule#K_DISCOURAGED}
- * 		or {@link IAccessRule#K_NON_ACCESSIBLE}.
- * 		The default returned value is {@link IAccessRule#K_ACCESSIBLE}.
- *
- * @since 3.6
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the source range of this import declaration's name,
+ * or null if this import declaration does not have
+ * associated source code (for example, a binary type)
+ * @since 3.7
  */
-public abstract int getAccessibility();
+ISourceRange getNameRange() throws JavaModelException;
 </pre>
-See bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296277">296277</a> for more details.
 </li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296277">296277</a>
-[search] SearchEngine#searchAllTypeNames(.., TypeNameMatchRequestor,..) should report access rules
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296708">296708</a>
-[DOM/AST] clarify setters when createASTs(..) is used
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296629">296629</a>
-[quick fix] Cast quick fix not offered for method-local classes
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295948">295948</a>
-ElementImpl.hashCode throws an NPE
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=296660">296660</a>
-[compiler] Incorrect unused method warning from compiler
-
-<a name="v_A24"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M4 - December 1, 2009
-<br>Project org.eclipse.jdt.core v_A24
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A24">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>New API added to ignore method bodies inside AST tree. The new APIs are tagged as 3.5.2 as this code
-will be backported to 3.5.2:
+<li>
+New API added to be able to retrieve the name range for <code>org.eclipse.jdt.core.IPackageDeclaration</code>:
 <pre>
-org.eclipse.jdt.core.dom.ASTParser:
-	/**
-	 * Requests an abstract syntax tree without method bodies. 
-	 * 
-	 * When ignore method bodies is enabled, all method bodies are discarded.
-	 * This has no impact on the binding resolution.
-	 *
-	 * If a method contains local types, its method body will be retained.
-	 * This settings is not used if the kind used in setKind(int) is either 
-	 * K_EXPRESSION or K_STATEMENTS.
-	 * @since 3.5.2
-	 */
-	public void setIgnoreMethodBodies(boolean enabled);
-
-org.eclipse.jdt.core.ICompilationUnit:
-	/**
-	 * Constant indicating that a reconcile operation could ignore to parse the method bodies.
-	 * @see ASTParser#setIgnoreMethodBodies(boolean)
-	 * @since 3.5.2
-	 */
-	public static final int IGNORE_METHOD_BODIES = 0x08;
-
+/**
+ * Returns the source range of this package declaration's name,
+ * or null if this package declaration does not have
+ * associated source code (for example, a binary type).
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ *      exception occurs while accessing its corresponding resource.
+ * @return the source range of this package declaration's name,
+ * or null if this package declaration does not have
+ * associated source code (for example, a binary type)
+ * @since 3.7
+ */
+ISourceRange getNameRange() throws JavaModelException;
 </pre>
 </li>
 </ul>
 
 <h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288174">288174</a>
-[search] NullPointerException when searching for type references
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643">277643</a>
-Generics compile error
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288211">288211</a>
-APT uses a lot of memory
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306524">306524</a>
+ASTRewriteAnalyzer uses wrong starting offset in case of comments before a node
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=150980">150980</a>
+[API] Selecting import declaration with space in outline highlights wrong range
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320841">320841</a>
+TypeConverters don't set enclosingType
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320802">320802</a>
+ASTParser.createASTs(..) fails silently on multiple missing parameter types.
 
-<a name="v_A23"></a>
+<a name="v_B04"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - November 24, 2009
-<br>Project org.eclipse.jdt.core v_A23
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A23">cvs</a>).
+Eclipse SDK 3.7M1 - July 27, 2010
+<br>Project org.eclipse.jdt.core v_B04
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B04">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=295698">295698</a>
-[1.5][compiler] ClassCastException in unchecked warning report
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295260">295260</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=190737">190737</a>
-[compiler][null] missing 'cannot be null' warning within for loop
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319425">319425</a>
+[compiler] JDT outputs corrupt .class file for problem type
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319885">319885</a>
+Spurious 'cycle detected'/'hierarchy inconsistent' errors if a type that WOULD be cyclic is static-imported
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=312076">312076</a>
+[1.5][compiler] Eclipse compiler behaves differently from javac
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320414">320414</a>
+Compiler produces incorrect bytecode for null pointer check
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=223225">223225</a>
+[DOM] IMemberValuePairBinding does not desugar single values into one-element arrays
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319603">319603</a>
+[1.5][compiler] eclipse fails with 2 generics methods with the same name while javac succeeds
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318020">318020</a>
+[compiler] wrong initialization flow info with if (true) throw... pattern in else block
 
-<a name="v_A22"></a>
+<a name="v_B03"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - November 16, 2009
-<br>Project org.eclipse.jdt.core v_A22
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A22">cvs</a>).
+Eclipse SDK 3.7M1 - July 20, 2010
+<br>Project org.eclipse.jdt.core v_B03
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B03">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=153429">153429</a>
-JUnit4 in Eclipse Testing Framework
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295238">295238</a>
-[formatter] The comment formatter add an unexpected new line in block comment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=295175">295175</a>
-[formatter] Missing space before a string at the beginning of a line in a javadoc comment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529">294529</a>
-The Scanner sometimes ignores the given offset if larger than the EOF.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294662">294662</a>
-ClassCastException while invoking quick assist
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294404">294404</a>
--target jsr14 flags error on foreach over Collection that does not implement Iterable
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293955">293955</a>
-valid javadoc url set on user library, but still says no javadoc
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293443">293443</a>
-AbortCompilation when invoking content assist
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293711">293711</a>
-Clarify ICompilationUnit#getOwner() javadoc
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293615">293615</a>
-error message since v3.6.0M2: name clash by overriding generic methods
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294618">294618</a>
-[formatter] The formatter fails to format a compilation unit with deep nesting of html tags
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=248312">248312</a>
-[model] IMemberValuePair#getValue() should also work for negative numerals
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294731">294731</a>
-Specify value type of JAVADOC_LOCATION_ATTRIBUTE_NAME
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=320340">320340</a>
+Test failures in debug mode
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=307523">307523</a>
+Differences between patch of bug 210422 and sources
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=319900">319900</a>
+StringLiteral#setLiteralValue needlessly escapes apostrophes (')
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310264">310264</a>
+Wrong warning: The assignment to variable has no effect
 
-<a name="v_A21"></a>
+<a name="v_B02"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - November 10, 2009
-<br>Project org.eclipse.jdt.core v_A21
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A21">cvs</a>).
+Eclipse SDK 3.7M1 - July 13, 2010
+<br>Project org.eclipse.jdt.core v_B02
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B02">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=294631">294631</a>
-[formatter] The formatter takes two passes to format a common sequence of html tags
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294500">294500</a>
-[formatter] MalformedTreeException when formatting an invalid sequence of &lt;code&gt; tags in a javadoc comment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294488">294488</a>
-Javadoc of ISourceReference#getSourceRange() should link to SourceRange#isAvailable(..)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=199265">199265</a>
-[formatter] 3.3 Code Formatter mis-places commented-out import statements
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=241549">241549</a>
-[spec] IType#getFields/Initializers/Methods() should define order from class file
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=275805">275805</a>
-creating a non-primary working copy causes typeHierarchyChanged event
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292510">292510</a>
-FUP of 292364: Error messages don't identify partial types precisely.
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=314556">314556</a>
+[1.5][compiler] compiler fails to report attempt to assign weaker access privileges
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=316956">316956</a>
+[compiler] Private superclass and enclosing scope field names incorrectly reported as conflicting
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=151500">151500</a>
+[assist] Method parameter names are not displayed for inner classes
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=304006">304006</a>
+[code assist] Autocast after instanceof feature doesnt work in some cases.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=210419">210419</a>
+[compiler] Invalid field initializer not flagged as error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=212713">212713</a>
+Bad error message for static block inside an interface
 
-<a name="v_A20"></a>
+<a name="v_B01"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M4 - November 3, 2009
-<br>Project org.eclipse.jdt.core v_A20
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A20">cvs</a>).
+Eclipse SDK 3.7M1 - July 6, 2010 - 3.7M1
+<br>Project org.eclipse.jdt.core v_B01
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B01">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=293384">293384</a>
-Eclipse erroneously reports method &quot;is ambiguous for type&quot;
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002">285002</a>
-[compiler] visibility error for package private method
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313153">313153</a>
+Too many blocked &quot;Refreshing external folders&quot; jobs (FUP of bug 302295)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=316654">316654</a>
+ITypeHierarchyChangedListener receive spurious callbacks
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317858">317858</a>
+Eclipse isn't accessing the correct field/class - causes compile error
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=318171">318171</a>
+fieldHiding-Warning does not appear if classes are in different packages
 
-<a name="v_A19"></a>
+<a name="v_B00"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 29, 2009 - 3.6M3
-<br>Project org.eclipse.jdt.core v_A19
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A19">cvs</a>).
-<h2>What's new in this drop</h2>
-This version was created to tentatively fix bug <a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293697">293697</a>
-but it occurs again in subsequent build. So, it has been reopened and moved to next version...
-
-<h3>Problem Reports Fixed</h3>
-
-<a name="v_A18"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 28, 2009
-<br>Project org.eclipse.jdt.core v_A18
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A18">cvs</a>).
+Eclipse SDK 3.7M1 - June 29, 2010
+<br>Project org.eclipse.jdt.core v_B00
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_B00">cvs</a>).
 <h2>What's new in this drop</h2>
 
 <h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293496">293496</a>
-Adding the serialVersionUID field doesn't work when tab size is 0
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317841">317841</a>
+[incremental build] unnecessary 'structural changes' due to annotation parameters
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317468">317468</a>
+Adding elements to an enum body with trailing comma generates bad code
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313668">313668</a>
+[search] Call hierarchy doesn't show all calls of the method in workspace
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317972">317972</a>
+Fix for wrong usages of affect* and effect*
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313651">313651</a>
+[formatter] format comments (differs between paste and save action)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=316889">316889</a>
+Internal compiler error: java.lang.NullPointerException with a specific use of recursive generics
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=315978">315978</a>
+Big regression, eclipse compiles my workspace in 3 mins instead of few seconds
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=315577">315577</a>
+[formatter] No line break after &lt;br&gt; if followed by {@link when formatting java source file
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=306464">306464</a>
+NPE in ProblemReporter.missingTypeInMethod(ProblemReporter.java:5113)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=317212">317212</a>
+[compiler] Illegal permission to invoke the constructor of a member class of an inaccessible type.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346">195346</a>
+[assist] Array type should be filtered while completing in case of a switch
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=315732">315732</a>
+[formatter] NullPointerException (always) on inserting a custom template proposal into java code when &quot;Use code formatter&quot; is on
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=316456">316456</a>
+[1.5][compiler] Annotation values can access private class members
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=312989">312989</a>
+Accepts illegal method-local classes if hidden by generics parameters
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423">310423</a>
+[content assist] After 'implements' annotation types should not be proposed
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=314830">314830</a>
+[compiler] Switching on a null expression doesn't always throw NullPointerException
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=313825">313825</a>
+Erroneous local variable's problems reported at surrounding ParenthesizedExpression
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=314898">314898</a>
+Typo in org.eclipse.jdt.core.dom.NameEnviromentWithProgress
 
-<a name="v_A17"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 26, 2009
-<br>Project org.eclipse.jdt.core v_A17
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A17">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>Reverted change for bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=263564">263564</a>.</li>
-</ul>
-<h3>Problem Reports Fixed</h3>
-
-<a name="v_A16"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 25, 2009
-<br>Project org.eclipse.jdt.core v_A16
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A16">cvs</a>).
-<h2>What's new in this drop</h2>
-
-<h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=293240">293240</a>
-[formatter] 'insert_space_before_opening_brace_in_array_initializer' preference may be reset in certain circumstances
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=263564">263564</a>
-API to know when default compiler preference settings have been altered
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=289385">289385</a>
-Investigate comment in performance tests
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=286379">286379</a>
-[search] Problem while searching class
-
-<a name="v_A15"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 20, 2009
-<br>Project org.eclipse.jdt.core v_A15
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A15">cvs</a>).
-<h2>What's new in this drop</h2>
-
-<h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=292350">292350</a>
-[1.5][compiler] Compiler error: ambiguous method since 3.5.1 using generics and interface inheritance
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=292364">292364</a>
-[internal] Type name in CastExpression not treated as Type name.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292428">292428</a>
-Internal compiler error: NullPointerException at org.eclipse.jdt.internal.compiler.ast.CastExpression.checkUnsafeCast(CastExpression.java:333)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291985">291985</a>
-[compiler][jsr14] Translating Enum with jsr14 target: ECJ causes a runtime error while Sun compiler works fine
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=292240">292240</a>
-Compiler error on implementation of raw sub interface
-
-<a name="v_A14"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 13, 2009
-<br>Project org.eclipse.jdt.core v_A14
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A14">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=291391">291391</a>
-update the Bundle-Version of the JDT Core Batch Compiler (ecj) from 3.3.0 to 3.6.*
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284280">284280</a>
-[1.5][compiler] Error on use generic interface in abstract super class
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286228">286228</a>
-[1.5][compiler] Generics inconsistencies possible regression
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286601">286601</a>
-[formatter] Code formatter formats anonymous inner classes wrongly when 'Never join lines' is on
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=215139">215139</a>
-[search] More options for HierarchyScope
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291472">291472</a>
-[1.5][compiler] Access to a generic method is compiled incorrectly
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283539">283539</a>
-NamingConventions.suggestVariableNames doesn't work if name contains '_'
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280784">280784</a>
-[batch] Allow access restrictions to be reported as errors
-
-<a name="v_A13"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - October 6, 2009
-<br>Project org.eclipse.jdt.core v_A13
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A13">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>Reverted fix for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=106478">106478</a>.</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291322">291322</a>
-Test errors when running JDT Core tests on Windows 7
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282770">282770</a>
-[compiler] Dead code detection should have specific @SuppressWarnings
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290028">290028</a>
-Use IResource#setDerived(boolean, IProgressMonitor) instead of IResource#setDerived(boolean)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287607">287607</a>
-[1.5][compiler] cast of inner of generic enclosing type are not reported as unsafe
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288749">288749</a>
-Redundant superinterface not flagged inside one declaration
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290905">290905</a>
-[formatter] Certain formatter pref constellation cause endless loop ==&gt; OOME
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285124">285124</a>
-serialVersionUID still causes error/warning
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290877">290877</a>
-[DOM] If using a tag named '@enum' the ASTParser ignores this
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281575">281575</a>
-Eclipse hangs in SourceMapper while doing java proposals
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290470">290470</a>
-[JSR199][compiler] JDT compiler not jsr199 compatible.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290730">290730</a>
-Rewriting SwitchStatement throws NPE
-
-<a name="v_A12"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - September 29, 2009
-<br>Project org.eclipse.jdt.core v_A12
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A12">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=287676">287676</a>
-[1.5][compiler] Useless cast warning not emited
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290563">290563</a>
-add specification for fine grain search flags
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290376">290376</a>
-Errant &quot;Comparing identical expressions&quot; warning with assignment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287592">287592</a>
-[1.5][compiler] Wrong ambiguous compilation error
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290049">290049</a>
-Reconciling a compilation unit does not return an AST with bindings when it should (probably)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=290034">290034</a>
-Effects of @SuppressWarnings(&quot;unchecked&quot;) are broader in Eclipse than in javac
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267561">267561</a>
-[evaluation] LocalEvaluationEngine does not accept primitive types
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=163194">163194</a>
-[1.6] compiler should warn about missing @Override annotation for interface method
-
-<a name="v_A11"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M3 - September 22, 2009
-<br>Project org.eclipse.jdt.core v_A11
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A11">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=289892">289892</a>
-[compiler] NPE during binaryTypeBinding field initialization
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287833">287833</a>
-[formatter] Formatter removes the first character after the * in the &lt;pre&gt; tag
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=238943">238943</a>
-SortElementsOperation doesn't use project specific settings
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288621">288621</a>
-[1.5][compiler] Creating type hierarchy failed when pressing F4
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289538">289538</a>
-[1.5][compiler] compiler fails to generate correct code for private constructor in inner class
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289639">289639</a>
-Problems opening perspective JavaPerspective, NPE on JavaModelManager.containersReset()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289516">289516</a>
-Annotations (visible and invisible) should be preserved with target jsr14
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289576">289576</a>
-[1.5][compiler] Compiler changes 'private' modifier on methods with annotated parameter
-
-<a name="v_A10"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M2 - September 14, 2009 - 3.6M2
-<br>Project org.eclipse.jdt.core v_A10
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A10">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=288148">288148</a>
-[perfs] Comments applied for performance tests may be obsolete
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=289247">289247</a>
-[1.5][compiler]Detecting duplicate methods should not consider return type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288920">288920</a>
-[compiler] NPE renaming run() method
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=288698">288698</a>
-Cannot create type hierarchy for abstract types when they have inline descendants and *.class* in project name
-
-<a name="v_A09"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M2 - September 1, 2009
-<br>Project org.eclipse.jdt.core v_A09
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A09">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=287009">287009</a>
-Inner Annotation Checks are Missing
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287701">287701</a>
-[dom] Length of Assignment should not include whitespace
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285230">285230</a>
-[performance] Duplicate buffers created for internal classes
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286391">286391</a>
-[compiler] jsr14 target behavior changed between ECJ 3.4.2 and ECJ 3.5
-
-<a name="v_A08"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M2 - August 25, 2009
-<br>Project org.eclipse.jdt.core v_A08
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A08">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=287462">287462</a>
-[formatter] new failures in last 2 nightly builds
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285565">285565</a>
-[inline] Inlining constant or local variables causes exceptions with tab width 0
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285799">285799</a>
-HashtableOfObject rehashes and grows buffer on removeKey()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286912">286912</a>
-[formatter] Never join lines preferences makes the formatter unstable in certain circumstances
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286668">286668</a>
-[formatter] 'Never Join Lines' joins lines that are split on method invocation
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=248661">248661</a>
-Axis2:  Missing required libraries in Axis 2 WS Client Projects
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286918">286918</a>
-[javadoc] Compiler should warn when @see and @link tag references in package-info.java don't have fully qualified names
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285466">285466</a>
-[3.5 regression] fails to build IcedTea, works with 3.4.x
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286956">286956</a>
-NPE when asking to externalize constant
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281609">281609</a>
-[javadoc] &quot;Javadoc: Invalid reference&quot; warning for @link to Java package
-
-<a name="v_A07"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M2 - August 18, 2009
-<br>Project org.eclipse.jdt.core v_A07
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A07">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=286840">286840</a>
-ClasspathJar getPath() should return a unique path
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=254738">254738</a>
-NPE in HierarchyResolver.setFocusType
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276294">276294</a>
-Error does not go away after it is resolved
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284785">284785</a>
-[1.5][compiler] Eclipse compiler shows error on javac-valid construct: varargs plus overload
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286405">286405</a>
-Default value character of annotations in ClassFileEditor are badly printed
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=286407">286407</a>
-[Model] IMemberValuePair don't return the right value for java.lang.annotation.RetentionPolicy annotations
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=285701">285701</a>
-[1.5][compiler] Internal Compiler Error - ArrayIndexOutOfBoundsException
-
-<a name="v_A06"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M1 - August 3, 2009 - 3.6M1
-<br>Project org.eclipse.jdt.core v_A06
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A06">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=284948">284948</a>
-[1.6][compiler] Java annotations are broken in editor when used on interface methods
-
-<a name="v_A05"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M1 - July 30, 2009
-<br>Project org.eclipse.jdt.core v_A05
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A05">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=276526">276526</a>
-[content assist] Error - Type Duplicate interface Iterable for the type TestClass
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=191176">191176</a>
-JavaProject#getOption optimizations
-
-<a name="v_A04"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M1 - July 28, 2009
-<br>Project org.eclipse.jdt.core v_A04
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A04">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=261909">261909</a>
-ClassFileReader.getModifiers() answers funny bits
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283225">283225</a>
-[1.6][compiler] classfile versus source conformance check too strict
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284679">284679</a>
-[formatter] empty single semi statement prevent enum elements format
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284482">284482</a>
-[compiler] Collision cases not detected
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=284431">284431</a>
-Different inherited thrown exception clauses are not properly handled
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=133911">133911</a>
-type.move() returns unclear exception &quot;invalid destination&quot;
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=270436">270436</a>
-[assist] Interface type proposed where only class is legal
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=210385">210385</a>
-[compiler] ProblemReporter#getProblemCategory misbehaves when passed ProblemSeverities.Ignore as severity parameter
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282891">282891</a>
-[compiler] "Comparing identical expressions" warning sometimes invalid
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282869">282869</a>
-[compiler] Unnecessary cast warning for cast from char to int
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=270437">270437</a>
-[assist] Completion proposal leads to cycle detected error
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=217443">217443</a>
-Documentation for JavaCore#CORE_ENCODING does not match the observed behavior
-
-<a name="v_A03"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M1 - July 21, 2009
-<br>Project org.eclipse.jdt.core v_A03
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A03">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=283467">283467</a>
-[formatter] wrong indentation with 'Never join lines' selected
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281776">281776</a>
-Should not warn for comparison of identical expression with float type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=282768">282768</a>
-[compiler] Dead code detection should ignore trivial case for ternary if operator
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283133">283133</a>
-[formatter] IAE when pasting a snippet
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=283299">283299</a>
-Complete SourceRange API
-
-<a name="v_A02"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java Development Tooling Core</h1>
-Eclipse SDK 3.6M1 - July 13, 2009
-<br>Project org.eclipse.jdt.core v_A02
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A02">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>Added new API type org.eclipse.jdt.core.SourceRange</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=271296">271296</a>
-[assist] void typed proposal may not be appropriate in many contexts
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281871">281871</a>
-[content assist] The extension took too long to return from the 'computeCompletionProposals()' operation
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281598">281598</a>
-[assist] Problems during content assist - if project has empty zip file in classpath
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235294">235294</a>
-[formatter] javadoc for DefaultCodeFormatterConstants#FORMATTER_ALIGNMENT_FOR_ASSIGNMENT cites a non-API constant
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280497">280497</a>
-Incorrect null result for IJavaProject.getClasspathEntryFor(IPath)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=204777">204777</a>
-Clarify documentation for ITypeHierarchy created on interface types
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=88265">88265</a>
-Make SourceRange API
-
-<a name="v_A01"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M1 - July 7, 2009
-<br>Project org.eclipse.jdt.core v_A01
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A01">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=260968">260968</a>
-Deadlock in UserLibraryManager
-
-<a name="v_A00"></a>
-<hr><h1>
-Eclipse Platform Build Notes<br>
-Java development tools core</h1>
-Eclipse SDK 3.6M1 - June 30, 2009
-<br>Project org.eclipse.jdt.core v_A00
-(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_A00">cvs</a>).
-<h2>What's new in this drop</h2>
-<ul>
-<li>New API added to handle the new <code>invokedynamic</code> bytecode:
-<pre>
-org.eclipse.jdt.core.util.ByteCodeVisitorAdapter:
-	public void _invokedynamic(
-			int pc,
-			int index,
-			IConstantPoolEntry nameEntry,
-			IConstantPoolEntry descriptorEntry) {
-		// default behavior is to do nothing
-	}
-</pre>
-<pre>org.eclipse.jdt.core.util.IBytecodeVisitor#_invokedynamic(int, int, IConstantPoolEntry, IConstantPoolEntry)</pre>
-<pre>org.eclipse.jdt.core.util.IOpcodeMnemonics#INVOKEDYNAMIC</pre>
-</li>
-</ul>
-
-<h3>Problem Reports Fixed</h3>
-<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277450">277450</a>
-[1.5][compiler] Problems with += and Autoboxing/Unboxing
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=206498">206498</a>
-[1.7][compiler] Remove fix for bug 206483 once 1.7 VMS can handle .class files with version 51.0
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=191176">191176</a>
-JavaProject#getOption optimizations
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=201762">201762</a>
-Content Assist has no proposals with certain CU structure
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281681">281681</a>
-Stale code in CompilerOptions
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=231796">231796</a>
-[formatter] @throws tag description is not indented using @param preference when there's a syntax error
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=255142">255142</a>
-[select] Codeselect should not omit cast
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=235295">235295</a>
-[formatter] javadoc of CodeFormatter#F_INCLUDE_COMMENTS needs improvement
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280134">280134</a>
-[1.5][compiler] Requesting Java AST from selection has encountered a problem
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=281317">281317</a>
-[search] An internal error occurred during: "Java Search".
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276373">276373</a>
-Incorrect resource comparison with IJavaProject.isOnClasspath(IResource)
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=275518">275518</a>
-[assist] Content assist does not provide proposals if invoked right after a method's opening brace
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280888">280888</a>
-change a java file in one plug-in will compile all related plugin projects
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=274466">274466</a>
-[assist] Assert expressions should be proposed with high relevance
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277382">277382</a>
-NPE and other failures in Parser
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=275330">275330</a>
-NPE from org.eclipse.jdt.internal.core.ClasspathChange.requestIndexing
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=273385">273385</a>
-[model] NPE while closing project
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280079">280079</a>
-NPE while parsing K_CLASS_BODY_DECLARATIONS
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280063">280063</a>
-org.eclipse.jdt.internal.compiler.parser.Parser.parseClassBodyDeclarations(char[], int, int, CompilationUnitDeclaration) should return consistent results
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267046">267046</a>
-SourceMapper infinite loop on primitive type in generic
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=240934">240934</a>
-Add support for the invokedynamic bytecode into the disassembler
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=267551">267551</a>
-[formatter] Wrong spacing in default array parameter for annotation type
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277965">277965</a>
-[compiler] NPE in canBeSeenBy due to illegal protected toplevel class
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=273990">273990</a>
-[compiler] FUP of 269388: Eclipse accepts code rejected by javac
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279183">279183</a>
-[1.6][compiler] Inconsistent stackmap frames generated by JDT cause VerifyError
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=209778">209778</a>
-[search] TypeReferenceMatch#getOtherElements() fails for match in annotation
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=221065">221065</a>
-[search] Search still finds overridden method
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279836">279836</a>
-[1.5][compiler] Eclipse compiler shows error on javac-valid construct: raw types on overridden methods
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280616">280616</a>
-[formatter] Valid 1.5 code is not formatted inside &lt;pre&gt; tag
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280255">280255</a>
-[formatter] Format edited lines adds two new lines on each save
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=280061">280061</a>
-[formatter] AIOOBE while formatting javadoc comment
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276938">276938</a>
-Remove unreachable removes reachable logic in case statement.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=274898">274898</a>
-[recovery] IllegalArgumentException in ASTNode#setSourceRange()
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=277204">277204</a>
-IAE in SharedASTProvider for generic local class.
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276741">276741</a>
-comparing identical value detection does not work for this
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=276740">276740</a>
-comparing identical value detection does not work for primitive types
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=278745">278745</a>
-Methods overloaded with unavailable types worked in 3.4 but give "indirectly referenced.." error in 3.5
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=278305">278305</a>
-[1.5][compiler] JDT accepts supertype parameterized with wildcard
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=196308">196308</a>
-[formatter] Don't escape entity when formatting in &lt;pre&gt; tags within javadoc comments
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=279359">279359</a>
-[formatter] Formatter with 'never join lines' produces extra level of indent
-<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=273619">273619</a>
-[formatter] Formatting repeats *} in javadoc
 
 <hr>
-<p>For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R35_buildnotes_jdt-core.html">build notes up to Release 3.5</a>.</p>
+<p>For earlier build notes, also see <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/org.eclipse.jdt.core/notes/R36_buildnotes_jdt-core.html">build notes up to Release 3.6</a>.</p>
 <br>
   <p>
     <a href="http://validator.w3.org/check?uri=referer"><img
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 015ff5e..8e413de 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
@@ -73,6 +73,7 @@
 import org.eclipse.jdt.internal.core.SearchableEnvironment;
 import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
 import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
+import org.eclipse.jdt.internal.core.search.matching.MatchLocator;
 import org.eclipse.jdt.internal.core.util.Messages;
 import org.eclipse.objectteams.otdt.core.IOTType;
 import org.eclipse.objectteams.otdt.core.OTModelManager;
@@ -530,6 +531,8 @@
 	private final static int SUPERTYPE = 1;
 	private final static int SUBTYPE = 2;
 	
+	private final static char[] DOT_ENUM = ".enum".toCharArray(); //$NON-NLS-1$
+	
 	int expectedTypesPtr = -1;
 	TypeBinding[] expectedTypes = new TypeBinding[1];
 	int expectedTypesFilter;
@@ -552,8 +555,10 @@
 	boolean assistNodeIsConstructor;
 	boolean assistNodeIsSuperType;
 	boolean assistNodeIsExtendedType;
+	boolean assistNodeIsInterfaceExcludingAnnotation; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423
 	int  assistNodeInJavadoc = 0;
 	boolean assistNodeCanBeSingleMemberAnnotation = false;
+	boolean assistNodeIsInsideCase = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
 	
 	long targetedElement;
 //{ObjectTeams:
@@ -650,6 +655,7 @@
 		public void setFieldIndex(int depth){/* empty */}
 		public int sourceEnd() { return 0; 	}
 		public int sourceStart() { return 0; 	}
+		public TypeBinding expectedType() { return null; }
 	};
 
 	private int foundTypesCount;
@@ -2896,6 +2902,7 @@
 			this.assistNodeIsInterface = ref.isInterface();
 			this.assistNodeIsSuperType = ref.isSuperType();
 			this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
+			this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
 
 			this.completionToken = ref.completionIdentifier;
 			long completionPosition = ref.sourcePositions[ref.tokens.length];
@@ -2958,6 +2965,37 @@
 		return false;
 	}
 	
+	private boolean assistNodeIsInterfaceExcludingAnnotation(ASTNode astNode, ASTNode astNodeParent) {
+		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423, don't propose annotations for implements.
+		if (astNodeParent == null)
+			return false;
+		if (astNodeParent instanceof TypeDeclaration) {
+			TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent;
+			TypeReference [] superInterfaces = typeDeclaration.superInterfaces;
+			int length = superInterfaces == null ? 0 : superInterfaces.length;
+			for (int i = 0; i < length; i++) {
+				if (superInterfaces[i] == astNode)
+					return true;
+			}
+		}
+		return false;
+	}
+	
+	private boolean assistNodeIsInsideCase(ASTNode astNode, ASTNode astNodeParent) {
+		// To find whether we're completing inside the case expression in a 
+		// switch case construct (https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346)
+		if (astNodeParent instanceof SwitchStatement) {
+			CaseStatement[] cases = ((SwitchStatement) astNodeParent).cases;
+			for (int i = 0, caseCount = ((SwitchStatement) astNodeParent).caseCount; i < caseCount; i++) {
+				CompletionNodeDetector detector = new CompletionNodeDetector(astNode, cases[i]);
+				if (detector.containsCompletionNode()) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
 	private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
 		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
 
@@ -3014,6 +3052,7 @@
 			(CompletionOnQualifiedNameReference) astNode;
 		this.completionToken = ref.completionIdentifier;
 		long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
+		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, this.parser.assistNodeParent);
 
 		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
 			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
@@ -3157,7 +3196,9 @@
 		this.assistNodeIsConstructor = ref.isConstructorType;
 		this.assistNodeIsSuperType = ref.isSuperType();
 		this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
-
+		this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
+		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, astNodeParent);
+		
 		this.completionToken = ref.completionIdentifier;
 		long completionPosition = ref.sourcePositions[ref.tokens.length];
 
@@ -3217,6 +3258,7 @@
 		CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
 		this.completionToken = singleNameReference.token;
 		SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
+		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, astNodeParent);
 		if (switchStatement != null
 				&& switchStatement.expression.resolvedType != null
 				&& switchStatement.expression.resolvedType.isEnum()) {
@@ -3298,7 +3340,9 @@
 		this.assistNodeIsConstructor = singleRef.isConstructorType;
 		this.assistNodeIsSuperType = singleRef.isSuperType();
 		this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
-
+		this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
+		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, astNodeParent);
+		
 		// can be the start of a qualified type name
 		if (qualifiedBinding == null) {
 			if (this.completionToken.length == 0 &&
@@ -4233,6 +4277,13 @@
 		}
 		return 0;
 	}
+	
+	private int computeRelevanceForFinal(boolean onlyFinal, boolean isFinal) {
+		if (onlyFinal && isFinal) {
+			return R_FINAL;
+		}
+		return 0;
+	}
 
 	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
 		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
@@ -6178,6 +6229,20 @@
 // SH}
 			if (this.options.checkVisibility
 				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
+			
+			// don't propose array types in case expression
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
+			if (this.assistNodeIsInsideCase && field.type instanceof ArrayBinding)
+				continue next;
+			
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=310427
+			// Don't propose field which is being declared currently
+			// Don't propose fields declared after the current field declaration statement
+			if (this.parser.assistNodeParent instanceof FieldDeclaration) {
+				FieldDeclaration fieldDeclaration = (FieldDeclaration) this.parser.assistNodeParent;
+				if (field.id >= fieldDeclaration.binding.id)
+					continue next;
+			}
 
 //{ObjectTeams: additional check if method spec type already known:
 		    if (expectedType != null && expectedType != field.type) continue next;
@@ -6291,6 +6356,7 @@
 			relevance += computeRelevanceForExpectingType(field.type);
 			relevance += computeRelevanceForEnumConstant(field.type);
 			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
+			relevance += computeRelevanceForFinal(this.assistNodeIsInsideCase, field.isFinal());
 			relevance += computeRelevanceForQualification(prefixRequired);
 			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
 			if (onlyStaticFields && this.insideQualifiedReference) {
@@ -7005,133 +7071,142 @@
 		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
 
 		IfStatement ifStatement = (IfStatement)enclosingNode;
-
-		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
-
-		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
-
-		TypeReference instanceOfType = instanceOfExpression.type;
-
-		if (instanceOfType.resolvedType == null) return;
-
-		boolean findFromAnotherReceiver = false;
-
-		char[][] receiverName = null;
-		int receiverStart = -1;
-		int receiverEnd = -1;
-
-		if (receiver instanceof QualifiedNameReference) {
-			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
-
-			receiverName = qualifiedNameReference.tokens;
-
-			if (receiverName.length != 1) return;
-
-			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
-			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
-
-			// if (local instanceof X) local.|
-			// if (field instanceof X) field.|
-			if (instanceOfExpression.expression instanceof SingleNameReference &&
-					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
-					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
-				findFromAnotherReceiver = true;
-			}
-
-			// if (this.field instanceof X) field.|
-			if (instanceOfExpression.expression instanceof FieldReference) {
-				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
-
-				if (fieldReference.receiver instanceof ThisReference &&
-						qualifiedBinding instanceof FieldBinding &&
-						fieldReference.binding == qualifiedBinding) {
-							findFromAnotherReceiver = true;
-				}
-			}
-		} else if (receiver instanceof FieldReference) {
-			FieldReference fieldReference1 = (FieldReference) receiver;
-
-			receiverStart = fieldReference1.sourceStart;
-			receiverEnd = fieldReference1.sourceEnd + 1;
-
-			if (fieldReference1.receiver instanceof ThisReference) {
-
-				receiverName = new char[][] {THIS, fieldReference1.token};
-
-				// if (field instanceof X) this.field.|
+		while (true) {
+			if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
+	
+			InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
+	
+			TypeReference instanceOfType = instanceOfExpression.type;
+	
+			if (instanceOfType.resolvedType == null) return;
+	
+			boolean findFromAnotherReceiver = false;
+	
+			char[][] receiverName = null;
+			int receiverStart = -1;
+			int receiverEnd = -1;
+	
+			if (receiver instanceof QualifiedNameReference) {
+				QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
+	
+				receiverName = qualifiedNameReference.tokens;
+	
+				if (receiverName.length != 1) return;
+	
+				receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
+				receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
+	
+				// if (local instanceof X) local.|
+				// if (field instanceof X) field.|
 				if (instanceOfExpression.expression instanceof SingleNameReference &&
-						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
+						((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
+						(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
 					findFromAnotherReceiver = true;
 				}
-
-				// if (this.field instanceof X) this.field.|
+	
+				// if (this.field instanceof X) field.|
 				if (instanceOfExpression.expression instanceof FieldReference) {
-					FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
-
-					if (fieldReference2.receiver instanceof ThisReference &&
-							fieldReference2.binding == fieldReference1.binding) {
+					FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
+	
+					if (fieldReference.receiver instanceof ThisReference &&
+							qualifiedBinding instanceof FieldBinding &&
+							fieldReference.binding == qualifiedBinding) {
 								findFromAnotherReceiver = true;
 					}
 				}
+			} else if (receiver instanceof FieldReference) {
+				FieldReference fieldReference1 = (FieldReference) receiver;
+	
+				receiverStart = fieldReference1.sourceStart;
+				receiverEnd = fieldReference1.sourceEnd + 1;
+	
+				if (fieldReference1.receiver instanceof ThisReference) {
+	
+					receiverName = new char[][] {THIS, fieldReference1.token};
+	
+					// if (field instanceof X) this.field.|
+					if (instanceOfExpression.expression instanceof SingleNameReference &&
+							((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
+						findFromAnotherReceiver = true;
+					}
+	
+					// if (this.field instanceof X) this.field.|
+					if (instanceOfExpression.expression instanceof FieldReference) {
+						FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
+	
+						if (fieldReference2.receiver instanceof ThisReference &&
+								fieldReference2.binding == fieldReference1.binding) {
+									findFromAnotherReceiver = true;
+						}
+					}
+				}
 			}
-		}
-
-		if (findFromAnotherReceiver) {
-			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
-			char[] castedReceiver = null;
-
-			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
-			if(this.source != null) {
-				int memberRefStart = this.startPosition;
-
-				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
-				char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
-
-				castedReceiver =
-					CharOperation.concat(
+	
+			if (findFromAnotherReceiver) {
+				TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
+				char[] castedReceiver = null;
+	
+				char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
+				if(this.source != null) {
+					int memberRefStart = this.startPosition;
+	
+					char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
+					char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
+	
+					castedReceiver =
 						CharOperation.concat(
-							'(',
 							CharOperation.concat(
-								CharOperation.concat('(', castedTypeChars, ')'),
-								receiverChars),
-							')'),
-						dotChars);
+								'(',
+								CharOperation.concat(
+									CharOperation.concat('(', castedTypeChars, ')'),
+									receiverChars),
+								')'),
+							dotChars);
+				} else {
+					castedReceiver =
+						CharOperation.concat(
+							CharOperation.concat(
+								'(',
+								CharOperation.concat(
+									CharOperation.concat('(', castedTypeChars, ')'),
+									CharOperation.concatWith(receiverName, '.')),
+								')'),
+							DOT);
+				}
+	
+				if (castedReceiver == null) return;
+	
+				int oldStartPosition = this.startPosition;
+				this.startPosition = receiverStart;
+	
+				findFieldsAndMethods(
+						this.completionToken,
+						receiverTypeBinding,
+						scope,
+						fieldsFound,
+						methodsFound,
+						invocationSite,
+						invocationScope,
+						false,
+						false,
+						null,
+						null,
+						null,
+						false,
+						castedReceiver,
+						receiverStart,
+						receiverEnd);
+	
+				this.startPosition = oldStartPosition;
+			}
+			// traverse the enclosing node to find the instanceof expression corresponding
+			// to the completion node (if any)
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304006
+			if (ifStatement.thenStatement instanceof IfStatement) {
+				ifStatement = (IfStatement) ifStatement.thenStatement;
 			} else {
-				castedReceiver =
-					CharOperation.concat(
-						CharOperation.concat(
-							'(',
-							CharOperation.concat(
-								CharOperation.concat('(', castedTypeChars, ')'),
-								CharOperation.concatWith(receiverName, '.')),
-							')'),
-						DOT);
+				break;
 			}
-
-			if (castedReceiver == null) return;
-
-			int oldStartPosition = this.startPosition;
-			this.startPosition = receiverStart;
-
-			findFieldsAndMethods(
-					this.completionToken,
-					receiverTypeBinding,
-					scope,
-					fieldsFound,
-					methodsFound,
-					invocationSite,
-					invocationScope,
-					false,
-					false,
-					null,
-					null,
-					null,
-					false,
-					castedReceiver,
-					receiverStart,
-					receiverEnd);
-
-			this.startPosition = oldStartPosition;
 		}
 	}
 	private void findFieldsAndMethodsFromFavorites(
@@ -9811,6 +9886,7 @@
 			typesFound.add(memberType);
 
 			if (this.assistNodeIsExtendedType && memberType.isFinal()) continue next;
+			if (this.assistNodeIsInterfaceExcludingAnnotation && memberType.isAnnotationType()) continue next;
 			if(!this.insideQualifiedReference) {
 				if(this.assistNodeIsClass) {
 //{ObjectTeams: different determination of class/interface for roles:
@@ -10409,6 +10485,7 @@
 								}
 
 								if (this.assistNodeIsExtendedType && localType.isFinal()) continue next;
+								if (this.assistNodeIsInterfaceExcludingAnnotation && localType.isAnnotationType()) continue next;
 								if(this.assistNodeIsClass) {
 									if(!localType.isClass()) continue next;
 								} else if(this.assistNodeIsInterface) {
@@ -10903,6 +10980,7 @@
 				typesFound.add(sourceType);
 
 				if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue next;
+				if (this.assistNodeIsInterfaceExcludingAnnotation && sourceType.isAnnotationType()) continue next;
 				if(this.assistNodeIsClass) {
 					if(!sourceType.isClass()) continue next;
 				} else if(this.assistNodeIsInterface) {
@@ -11036,6 +11114,8 @@
 				int searchFor = IJavaSearchConstants.TYPE;
 				if(this.assistNodeIsClass) {
 					searchFor = IJavaSearchConstants.CLASS;
+				} else if (this.assistNodeIsInterfaceExcludingAnnotation) {
+					searchFor = IJavaSearchConstants.INTERFACE;
 				} else if(this.assistNodeIsInterface) {
 					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
 				} else if(this.assistNodeIsEnum) {
@@ -11128,6 +11208,7 @@
 					continue;
 
 			    if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue;
+			    if (this.assistNodeIsInterfaceExcludingAnnotation && sourceType.isAnnotationType()) continue;
 				int accessibility = IAccessRule.K_ACCESSIBLE;
 				if(sourceType.hasRestrictedAccess()) {
 					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
@@ -11215,6 +11296,8 @@
 			int searchFor = IJavaSearchConstants.TYPE;
 			if(this.assistNodeIsClass) {
 				searchFor = IJavaSearchConstants.CLASS;
+			} else if (this.assistNodeIsInterfaceExcludingAnnotation) {
+				searchFor = IJavaSearchConstants.INTERFACE;
 			} else if(this.assistNodeIsInterface) {
 				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
 			} else if(this.assistNodeIsEnum) {
@@ -11321,6 +11404,7 @@
 						}
 
 						if (this.assistNodeIsExtendedType && refBinding.isFinal()) continue next;
+						if (this.assistNodeIsInterfaceExcludingAnnotation && refBinding.isAnnotationType()) continue next;
 						if(this.assistNodeIsClass) {
 							if(!refBinding.isClass()) continue next;
 						} else if(this.assistNodeIsInterface) {
@@ -11451,6 +11535,7 @@
 							typesFound.add(typeBinding);
 							
 							if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue;
+							if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue;
 							if(this.assistNodeIsClass) {
 								if(!typeBinding.isClass()) continue;
 							} else if(this.assistNodeIsInterface) {
@@ -11554,6 +11639,7 @@
 							typesFound.add(typeBinding);
 
 							if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue;
+							if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue;
 							if(this.assistNodeIsClass) {
 								if(!typeBinding.isClass()) continue;
 							} else if(this.assistNodeIsInterface) {
@@ -12077,6 +12163,21 @@
 // carp}
 							if (local.isSecret())
 								continue next;
+												
+							// don't propose array types in case expression
+							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
+							if (this.assistNodeIsInsideCase && local.type instanceof ArrayBinding)
+								continue next;
+							
+							int ptr = this.uninterestingBindingsPtr;
+							// Cases where the binding is uninteresting eg. for completion occurring inside a local var
+							// declaration, the local var binding is uninteresting and shouldn't be proposed.
+							while (ptr >= 0) {
+								if (this.uninterestingBindings[ptr] == local) {
+									continue next;
+								}
+								ptr--;
+							}
 
 							for (int f = 0; f < localsFound.size; f++) {
 								LocalVariableBinding otherLocal =
@@ -12094,6 +12195,7 @@
 							relevance += computeRelevanceForEnumConstant(local.type);
 							relevance += computeRelevanceForQualification(false);
 							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
+							relevance += computeRelevanceForFinal(this.assistNodeIsInsideCase, local.isFinal());
 							this.noProposal = false;
 							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
 								InternalCompletionProposal proposal =  createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
@@ -12486,6 +12588,14 @@
 				}
 			}
 		}
+		
+		// filter packages ending with enum for projects above 1.5 
+		// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264
+		if (MatchLocator.SHOULD_FILTER_ENUM && this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5 &&
+				CharOperation.endsWith(givenPkgName, DOT_ENUM)) { //note: it should be .enum and not just enum
+				return true;
+		}
+		
 		return false;
 	}
 
@@ -13391,18 +13501,7 @@
 			// treating MethodSpec(long) like a call, we need a fake InvocationSite:
 			InvocationSite site = null;
 			if (methodSpec.hasSignature)
-				site = new InvocationSite() {
-							public TypeBinding[] genericTypeArguments() { return null; }
-							public boolean isSuperAccess() { return false; }
-							public boolean isTypeAccess() { return false; }
-							public void setActualReceiverType(ReferenceBinding receiverType) {}
-							public void setDepth(int depth) {
-								// TODO Auto-generated method stub
-							}
-							public void setFieldIndex(int depth) {}
-							public int sourceEnd() { return end; }
-							public int sourceStart() { return start; }
-						};
+				site = FakeInvocationSite;
 			try {
 				this.currentMethodMapping = mapping;
 				findMethods(
@@ -13523,18 +13622,7 @@
 		// treating FieldAccessSpec(long) like a field access, we need a fake InvocationSite:
 		InvocationSite site = null;
 		if (hasSignature)
-			site = new InvocationSite() {
-						public TypeBinding[] genericTypeArguments() { return null; }
-						public boolean isSuperAccess() { return false; }
-						public boolean isTypeAccess() { return false; }
-						public void setActualReceiverType(ReferenceBinding receiverType) {}
-						public void setDepth(int depth) {
-							// TODO Auto-generated method stub
-						}
-						public void setFieldIndex(int depth) {}
-						public int sourceEnd() { return end; }
-						public int sourceStart() { return start; }
-					};
+			site = FakeInvocationSite;
 		ObjectVector fieldsFound = new ObjectVector();
 		findFields(
 				this.completionToken,
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 3a09a48..7b4e0e8 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
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Andreas Magnusson <andreas.ch.magnusson@gmail.com>- contribution for bug 151500
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.codeassist;
@@ -195,7 +196,8 @@
 			}
 		} else {
 			// TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ?
-			NameLookup.Answer answer = this.nameLookup.findType(new String(tName),
+			NameLookup.Answer answer = this.nameLookup.findType(new String(declaringTypeName),
+				new String(declaringTypePackageName),
 				false,
 				NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES,
 				true/* consider secondary types */,
@@ -211,21 +213,20 @@
 		}
 
 		if(type != null) {
-			String[] args = new String[length];
-			for(int i = 0;	i< length ; i++){
-				args[i] = new String(paramTypeNames[i]);
-			}
-			IMethod method = type.getMethod(new String(selector),args);
-			
-			if (this.hasNoParameterNamesFromIndex) {
-				IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
-				if (packageFragmentRoot.isArchive() ||
-						this.completionEngine.openedBinaryTypes < getOpenedBinaryTypesThreshold()) {
-					SourceMapper mapper = ((JavaElement)method).getSourceMapper();
-					if (mapper != null) {
-						try {
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937
+			// BinaryType#getMethod() creates a new instance of BinaryMethod, which is a dummy.
+			// Instead we have to use IType#findMethods() to get a handle to the method of our interest.
+			try {
+				IMethod method = findMethod(type, selector, paramTypeNames);
+				if (this.hasNoParameterNamesFromIndex) {
+
+					IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot)type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
+					if (packageFragmentRoot.isArchive() ||
+							this.completionEngine.openedBinaryTypes < getOpenedBinaryTypesThreshold()) {
+						SourceMapper mapper = ((JavaElement)method).getSourceMapper();
+						if (mapper != null) {
 							char[][] paramNames = mapper.getMethodParameterNames(method);
-					
+
 							// map source and try to find parameter names
 							if(paramNames == null) {
 								if (!packageFragmentRoot.isArchive()) this.completionEngine.openedBinaryTypes++;
@@ -236,35 +237,28 @@
 								}
 								paramNames = mapper.getMethodParameterNames(method);
 							}
-							
+
 							if(paramNames != null) {
 								parameters = paramNames;
 							}
-						} catch(JavaModelException e){
-							//parameters == null;
 						}
 					}
-				}
-			} else {
-				try{
+				} else {
 					IBinaryMethod info = (IBinaryMethod) ((JavaElement)method).getElementInfo();
 					char[][] argumentNames = info.getArgumentNames();
 					if (argumentNames != null && argumentNames.length == length) {
 						parameters = argumentNames;
+						return parameters;
 					}
-				} catch(JavaModelException e){
-					//parameters == null;
-				}
-				
-				try{
+
 					parameters = new char[length][];
 					String[] params = method.getParameterNames();
 					for(int i = 0;	i< length ; i++){
 						parameters[i] = params[i].toCharArray();
 					}
-				} catch(JavaModelException e){
-					parameters = null;
 				}
+			} catch(JavaModelException e){
+				parameters = null;
 			}
 		}
 
@@ -292,7 +286,8 @@
 			}
 		} else {
 			// TODO (david) shouldn't it be NameLookup.ACCEPT_ALL ?
-			NameLookup.Answer answer = this.nameLookup.findType(new String(tName),
+			NameLookup.Answer answer = this.nameLookup.findType(new String(declaringTypeName),
+				new String(declaringTypePackageName),
 				false,
 				NameLookup.ACCEPT_CLASSES & NameLookup.ACCEPT_INTERFACES,
 				true/* consider secondary types */,
@@ -308,12 +303,11 @@
 		}
 
 		if(type != null) {
-			String[] args = new String[length];
-			for(int i = 0;	i< length ; i++){
-				args[i] = new String(paramTypeNames[i]);
-			}
-			IMethod method = type.getMethod(new String(selector),args);
+			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=316937
+			// BinaryType#getMethod() creates a new instance of BinaryMethod, which is a dummy.
+			// Instead we have to use IType#findMethods() to get a handle to the method of our interest.
 			try{
+				IMethod method = findMethod(type, selector, paramTypeNames);
 				parameters = new char[length][];
 				String[] params = method.getParameterNames();
 				for(int i = 0;	i< length ; i++){
@@ -332,6 +326,35 @@
 		return parameters;
 	}
 
+	private IMethod findMethod(IType type, char[] selector, char[][] paramTypeNames) throws JavaModelException {
+		IMethod method = null;
+		int startingIndex = 0;
+		String[] args;
+		IType enclosingType = type.getDeclaringType();
+		// If the method is a constructor of a non-static inner type, add the enclosing type as an 
+		// additional parameter to the constructor
+		if (enclosingType != null
+				&& CharOperation.equals(type.getElementName().toCharArray(), selector)
+				&& !Flags.isStatic(type.getFlags())) {
+			args = new String[paramTypeNames.length+1];
+			startingIndex = 1;
+			args[0] = Signature.createTypeSignature(enclosingType.getFullyQualifiedName(), true);
+		} else {
+			args = new String[paramTypeNames.length];
+		}
+		int length = args.length;
+		for(int i = startingIndex;	i< length ; i++){
+			args[i] = new String(paramTypeNames[i-startingIndex]);
+		}
+		method = type.getMethod(new String(selector), args);
+		
+		IMethod[] methods = type.findMethods(method);
+		if (methods != null && methods.length > 0) {
+			method = methods[0];
+		}
+		return method;
+	}
+
 	protected char[] getDeclarationPackageName() {
 		return this.declarationPackageName;
 	}
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 4b85ad5..de5ec24 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
@@ -20,11 +20,11 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.WorkingCopyOwner;
 import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.codeassist.complete.CompletionNodeDetector;
 import org.eclipse.jdt.internal.codeassist.complete.CompletionParser;
 import org.eclipse.jdt.internal.codeassist.impl.AssistCompilationUnit;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.Initializer;
@@ -190,13 +190,39 @@
 							}
 						} else {
 							FieldDeclaration fieldDeclaration = fields[i];
-							if (fieldDeclaration.initialization != null &&
-									fieldDeclaration.initialization.sourceStart <= astNode.sourceStart &&
-									astNode.sourceEnd <= fieldDeclaration.initialization.sourceEnd) {
+							if (fieldDeclaration.initialization != null) {
 								// completion is inside a field initializer
 								searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc);
+								// remove this field from visibleFields list because completion is being asked in its
+								// intialization and so this has not yet been declared successfully.
+								if (this.visibleFields.size > 0 && this.visibleFields.contains(fieldDeclaration.binding)) {
+									this.visibleFields.remove(fieldDeclaration.binding);
+								}
 								break done;
 							}
+							/*(Incase fieldDeclaration != null is not sufficient to infer that
+							  proposal is being asked inside initializer of field decl, use the below if
+							  block instead of the above)
+							if (fieldDeclaration.initialization != null) {
+							 
+								if (fieldDeclaration.initialization.sourceEnd > 0) {
+									if (fieldDeclaration.initialization.sourceStart <= astNode.sourceStart &&
+											astNode.sourceEnd <= fieldDeclaration.initialization.sourceEnd) {
+										// completion is inside a field initializer
+										searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc);
+									}
+								} else { // The sourceEnd may not yet be set
+									CompletionNodeDetector detector = new CompletionNodeDetector(this.assistNode, fieldDeclaration.initialization);
+									if (detector.containsCompletionNode()) {
+										searchVisibleVariablesAndMethods(scope, this.visibleLocalVariables, this.visibleFields, this.visibleMethods, notInJavadoc);
+									}
+								}
+								// remove this field from visibleFields list because completion is being asked in its
+								// intialization and so this has not yet been declared successfully.
+								if (this.visibleFields.size > 0 && this.visibleFields.contains(fieldDeclaration.binding)) {
+									this.visibleFields.remove(fieldDeclaration.binding);
+								}
+							}*/
 						}
 					}
 				}
@@ -245,7 +271,9 @@
 				local.sourceStart,
 				local.sourceEnd,
 				Util.typeSignature(local.type),
-				binding.declaration.annotations);
+				binding.declaration.annotations,
+				local.modifiers,
+				local.getKind() == AbstractVariableDeclaration.PARAMETER);
 	}
 
 	private JavaElement getJavaElementOfCompilationUnit(Binding binding) {
@@ -736,11 +764,13 @@
 						// If the local variable declaration's initialization statement itself has the completion,
 						// then don't propose the local variable
 						if (local.declaration.initialization != null) {
-							if(local.declaration.initialization.sourceEnd > 0) {
-									if (this.assistNode.sourceEnd <= local.declaration.initialization.sourceEnd
-											&& this.assistNode.sourceStart >= local.declaration.initialization.sourceStart) {
-										continue next;
-									}
+							/*(use this if-else block if it is found that local.declaration.initialization != null is not sufficient to 
+							  guarantee that proposal is being asked inside a local variable declaration's initializer)
+							 if(local.declaration.initialization.sourceEnd > 0) {
+								if (this.assistNode.sourceEnd <= local.declaration.initialization.sourceEnd
+										&& this.assistNode.sourceStart >= local.declaration.initialization.sourceStart) {
+									continue next;
+								}
 							} else {
 								CompletionNodeDetector detector = new CompletionNodeDetector(
 										this.assistNode,
@@ -748,7 +778,8 @@
 								if (detector.containsCompletionNode()) {
 									continue next;
 								}
-							}
+							}*/
+							continue next;
 						}
 						for (int f = 0; f < localsFound.size; f++) {
 							LocalVariableBinding otherLocal =
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
index 72abf4f..3b17e51 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/RelevanceConstants.java
@@ -53,4 +53,5 @@
 	int R_NO_PROBLEMS = 1;
 	int R_RESOLVED = 1;
 	int R_TARGET = 5;
+	int R_FINAL = 3; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
index 5284162..fe6d941 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnPackageReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -41,10 +41,10 @@
 //{ObjectTeams: modifiers added:
 /*orig:
 public CompletionOnPackageReference(char[][] tokens , long[] positions) {
-	super(tokens, positions, true, ClassFileConstants.AccDefault);
+	super(tokens, positions, false, ClassFileConstants.AccDefault);
  :giro*/
 public CompletionOnPackageReference(char[][] tokens , long[] positions, int modifiers) {
-	super(tokens, positions, true, modifiers);
+	super(tokens, positions, false, modifiers);
 // SH}
 }
 public StringBuffer print(int indent, StringBuffer output, boolean withOnDemand) {
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 9df7f93..968ba90 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
@@ -597,8 +597,9 @@
 			if(expression == this.assistNode
 				|| (expression instanceof Assignment	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=287939
 					&& ((Assignment)expression).expression == this.assistNode
-					&& ((this.expressionPtr > 0 && this.expressionStack[this.expressionPtr - 1] instanceof InstanceOfExpression)
-						|| (this.elementPtr >= 0 && this.elementObjectInfoStack[this.elementPtr] instanceof InstanceOfExpression)))
+					&& ((this.expressionPtr > 0 && stackHasInstanceOfExpression(this.expressionStack, this.expressionPtr - 1))
+							// In case of error in compilation unit, expression stack might not have instanceof exp, so try elementObjectInfoStack
+						|| (this.elementPtr >= 0 && stackHasInstanceOfExpression(this.elementObjectInfoStack, this.elementPtr))))
 				|| (expression instanceof AllocationExpression
 					&& ((AllocationExpression)expression).type == this.assistNode)
 				|| (expression instanceof AND_AND_Expression
@@ -1106,7 +1107,7 @@
 	}
 }
 private Statement buildMoreCompletionEnclosingContext(Statement statement) {
-
+	IfStatement ifStatement = null;
 	int blockIndex = lastIndexOfElement(K_BLOCK_DELIMITER);
 	int controlIndex = lastIndexOfElement(K_CONTROL_STATEMENT_DELIMITER);
 	int index;
@@ -1119,42 +1120,63 @@
 		int instanceOfIndex = lastIndexOfElement(K_BETWEEN_INSTANCEOF_AND_RPAREN);
 		index = blockIndex != -1 && instanceOfIndex < blockIndex ? blockIndex : instanceOfIndex;
 	}
-	if (index != -1 && this.elementInfoStack[index] == IF && this.elementObjectInfoStack[index] != null) {
-		Expression condition = (Expression)this.elementObjectInfoStack[index];
-
-		// If currentElement is a RecoveredLocalVariable then it can be contained in the if statement
-		if (this.currentElement instanceof RecoveredLocalVariable &&
-				this.currentElement.parent instanceof RecoveredBlock) {
-			RecoveredLocalVariable recoveredLocalVariable = (RecoveredLocalVariable) this.currentElement;
-			if (recoveredLocalVariable.localDeclaration.initialization == null &&
-					statement instanceof Expression &&
-					condition.sourceStart < recoveredLocalVariable.localDeclaration.sourceStart) {
-				this.currentElement.add(statement, 0);
-
-				statement = recoveredLocalVariable.updatedStatement(0, new HashSet());
-
-				// RecoveredLocalVariable must be removed from its parent because the IfStatement will be added instead
-				RecoveredBlock recoveredBlock =  (RecoveredBlock) recoveredLocalVariable.parent;
-				recoveredBlock.statements[--recoveredBlock.statementCount] = null;
-
-				this.currentElement = recoveredBlock;
-
+	while (index >= 0) {
+		// Try to find an enclosing if statement even if one is not found immediately preceding the completion node.
+		if (index != -1 && this.elementInfoStack[index] == IF && this.elementObjectInfoStack[index] != null) {
+			Expression condition = (Expression)this.elementObjectInfoStack[index];
+	
+			// If currentElement is a RecoveredLocalVariable then it can be contained in the if statement
+			if (this.currentElement instanceof RecoveredLocalVariable &&
+					this.currentElement.parent instanceof RecoveredBlock) {
+				RecoveredLocalVariable recoveredLocalVariable = (RecoveredLocalVariable) this.currentElement;
+				if (recoveredLocalVariable.localDeclaration.initialization == null &&
+						statement instanceof Expression &&
+						condition.sourceStart < recoveredLocalVariable.localDeclaration.sourceStart) {
+					this.currentElement.add(statement, 0);
+	
+					statement = recoveredLocalVariable.updatedStatement(0, new HashSet());
+	
+					// RecoveredLocalVariable must be removed from its parent because the IfStatement will be added instead
+					RecoveredBlock recoveredBlock =  (RecoveredBlock) recoveredLocalVariable.parent;
+					recoveredBlock.statements[--recoveredBlock.statementCount] = null;
+	
+					this.currentElement = recoveredBlock;
+	
+				}
 			}
+			if (statement instanceof AND_AND_Expression && this.assistNode instanceof Statement) {
+				statement = (Statement) this.assistNode;
+			}
+			ifStatement =
+				new IfStatement(
+						condition,
+						statement,
+						condition.sourceStart,
+						statement.sourceEnd);
+			index--;
+			break;
 		}
-		if (statement instanceof AND_AND_Expression && this.assistNode instanceof Statement) {
-			statement = (Statement) this.assistNode;
-		}
-		IfStatement ifStatement =
-			new IfStatement(
-					condition,
-					statement,
-					condition.sourceStart,
-					statement.sourceEnd);
-		this.enclosingNode = ifStatement;
-		return ifStatement;
+		index--;
 	}
-
-	return statement;
+	if (ifStatement == null) {
+		return statement;
+	}
+	// collect all if statements with instanceof expressions that enclose the completion node
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304006
+	while (index >= 0) {
+		if (this.elementInfoStack[index] == IF && this.elementObjectInfoStack[index] instanceof InstanceOfExpression) {
+			InstanceOfExpression condition = (InstanceOfExpression)this.elementObjectInfoStack[index];
+			ifStatement =
+				new IfStatement(
+						condition,
+						ifStatement,
+						condition.sourceStart,
+						ifStatement.sourceEnd);
+		}
+		index--;
+	}
+	this.enclosingNode = ifStatement;
+	return ifStatement;
 }
 private void buildMoreGenericsCompletionContext(ASTNode node, boolean consumeTypeArguments) {
 	int kind = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER);
@@ -2455,6 +2477,21 @@
 		}
 	}
 }
+protected void consumeClassHeaderImplements() {
+	super.consumeClassHeaderImplements();
+	if (this.assistNode != null && this.assistNodeParent == null) {
+		TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
+		if (typeDecl != null) {
+			TypeReference[] superInterfaces = typeDecl.superInterfaces;
+			int length = superInterfaces == null ? 0 : superInterfaces.length;
+			for (int i = 0; i < length; i++) {
+				if (superInterfaces[i] == this.assistNode) {
+					this.assistNodeParent = typeDecl;
+				}	
+			}
+		}
+	}
+}
 protected void consumeClassTypeElt() {
 	pushOnElementStack(K_NEXT_TYPEREF_IS_EXCEPTION);
 	super.consumeClassTypeElt();
@@ -5100,6 +5137,21 @@
 		this.sourceEnds = new HashtableOfObjectToInt();
 	}
 }
+
+/*
+ * To find out if the given stack has an instanceof expression
+ * at the given startIndex or at one prior to that
+ */
+private boolean stackHasInstanceOfExpression(Object[] stackToSearch, int startIndex) {
+	int indexInstanceOf = startIndex;
+	while (indexInstanceOf >= 0) {
+		if (stackToSearch[indexInstanceOf] instanceof InstanceOfExpression) {
+			return true;
+		}
+		indexInstanceOf--;
+	}
+	return false;
+}
 /*
  * Reset internal state after completion is over
  */
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 75e2061..b30b7a5 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
@@ -800,6 +800,8 @@
 	/* build specific assist node on import statement */
 	ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccStatic);
 	reference.bits |= ASTNode.OnDemand;
+	// star end position
+	reference.trailingStarPosition = this.intStack[this.intPtr--];
 	this.assistNode = reference;
 	this.lastCheckPoint = reference.sourceEnd + 1;
 
@@ -922,6 +924,8 @@
 	/* build specific assist node on import statement */
 	ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccDefault);
 	reference.bits |= ASTNode.OnDemand;
+	// star end position
+	reference.trailingStarPosition = this.intStack[this.intPtr--];
 	this.assistNode = reference;
 	this.lastCheckPoint = reference.sourceEnd + 1;
 
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
index c3c659a..2ad2d3b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionOnPackageReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -38,10 +38,10 @@
 //{ObjectTeams: added: modifiers (for the sake of "team"):
 /* orig:
 public SelectionOnPackageReference(char[][] tokens , long[] positions) {
-	super(tokens, positions, true, ClassFileConstants.AccDefault);
+	super(tokens, positions, false, ClassFileConstants.AccDefault);
   :giro*/
 public SelectionOnPackageReference(char[][] tokens , long[] positions, int modifiers) {
-	super(tokens, positions, true, modifiers);
+	super(tokens, positions, false, modifiers);
 // SH}
 }
 public StringBuffer print(int tab, StringBuffer output, boolean withOnDemand) {
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 e0458b4..6d14848 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -995,6 +995,8 @@
 	/* build specific assist node on import statement */
 	ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccStatic);
 	reference.bits |= ASTNode.OnDemand;
+	// star end position
+	reference.trailingStarPosition = this.intStack[this.intPtr--];
 	this.assistNode = reference;
 	this.lastCheckPoint = reference.sourceEnd + 1;
 
@@ -1076,6 +1078,8 @@
 	/* build specific assist node on import statement */
 	ImportReference reference = createAssistImportReference(subset, positions, ClassFileConstants.AccDefault);
 	reference.bits |= ASTNode.OnDemand;
+	// star end position
+	reference.trailingStarPosition = this.intStack[this.intPtr--];
 	this.assistNode = reference;
 	this.lastCheckPoint = reference.sourceEnd + 1;
 
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 3d12a2d..88e3a62 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CharOperation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -2097,7 +2097,7 @@
 public static final int indexOf(final char[] toBeFound, final char[] array, final boolean isCaseSensitive, final int start, final int end) {
 	final int arrayLength = end;
 	final int toBeFoundLength = toBeFound.length;
-	if (toBeFoundLength > arrayLength) return -1;
+	if (toBeFoundLength > arrayLength || start < 0) return -1;
 	if (toBeFoundLength == 0) return 0;
 	if (toBeFoundLength == arrayLength) {
 		if (isCaseSensitive) {
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 2637605..491fb0f 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
@@ -814,6 +814,8 @@
 	int TooManyFields = Internal + 432;
 	/** @since 2.1 */
 	int TooManyMethods = Internal + 433;
+	/** @since 3.7 */
+	int TooManyParametersForSyntheticMethod = Internal + 434;
 
 	// 1.4 features
 	// assertion warning
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 5695680..ffa104b 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
@@ -48,10 +48,10 @@
 import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrame;
 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
-import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.ExceptionMarker;
 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackDepthMarker;
 import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream.StackMarker;
+import org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.impl.StringConstant;
@@ -61,7 +61,6 @@
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
@@ -266,7 +265,6 @@
 		LookupEnvironment env = typeBinding.scope.environment();
 		return env.classFilePool.acquire(typeBinding);
 	}
-
 	/**
 	 * INTERNAL USE-ONLY
 	 * This methods creates a new instance of the receiver.
@@ -304,8 +302,8 @@
 	 * @param methodBinding org.eclipse.jdt.internal.compiler.nameloopkup.MethodBinding
 	 */
 	public void addAbstractMethod(
-		AbstractMethodDeclaration method,
-		MethodBinding methodBinding) {
+			AbstractMethodDeclaration method,
+			MethodBinding methodBinding) {
 
 //{ObjectTeams: role ifc methods may have funny modifiers (static, callin), don't destroy the original binding 
 		if (methodBinding.declaringClass.isSynthInterface())
@@ -313,8 +311,8 @@
 // SH}
 		this.generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
-		int attributeNumber = this.generateMethodInfoAttribute(methodBinding);
-		completeMethodInfo(methodAttributeOffset, attributeNumber);
+		int attributeNumber = this.generateMethodInfoAttributes(methodBinding);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
 	}
 
 	/**
@@ -344,26 +342,7 @@
 			if (lastIndex != -1) {
 				fullFileName = fullFileName.substring(lastIndex + 1, fullFileName.length());
 			}
-			// check that there is enough space to write all the bytes for the field info corresponding
-			// to the @fieldBinding
-			if (this.contentsOffset + 8 >= this.contents.length) {
-				resizeContents(8);
-			}
-			int sourceAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.SourceName);
-			this.contents[this.contentsOffset++] = (byte) (sourceAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) sourceAttributeNameIndex;
-			// The length of a source file attribute is 2. This is a fixed-length
-			// attribute
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 2;
-			// write the source file name
-			int fileNameIndex = this.constantPool.literalIndex(fullFileName.toCharArray());
-			this.contents[this.contentsOffset++] = (byte) (fileNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) fileNameIndex;
-			attributesNumber++;
+			attributesNumber += generateSourceAttribute(fullFileName);
 		}
 //{ObjectTeams: write OT-specific attributes:
         attributesNumber += ModelElement.writeAttributes(this.referenceBinding, this);
@@ -392,81 +371,18 @@
 		if (this.referenceBinding.isDeprecated()) {
 			// check that there is enough space to write all the bytes for the field info corresponding
 			// to the @fieldBinding
-			if (this.contentsOffset + 6 >= this.contents.length) {
-				resizeContents(6);
-			}
-			int deprecatedAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
-			this.contents[this.contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) deprecatedAttributeNameIndex;
-			// the length of a deprecated attribute is equals to 0
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			attributesNumber++;
+			attributesNumber += generateDeprecatedAttribute();
 		}
 		// add signature attribute
 		char[] genericSignature = this.referenceBinding.genericSignature();
 		if (genericSignature != null) {
-			// check that there is enough space to write all the bytes for the field info corresponding
-			// to the @fieldBinding
-			if (this.contentsOffset + 8 >= this.contents.length) {
-				resizeContents(8);
-			}
-			int signatureAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.SignatureName);
-			this.contents[this.contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) signatureAttributeNameIndex;
-			// the length of a signature attribute is equals to 2
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 2;
-			int signatureIndex =
-				this.constantPool.literalIndex(genericSignature);
-			this.contents[this.contentsOffset++] = (byte) (signatureIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) signatureIndex;
-			attributesNumber++;
+			attributesNumber += generateSignatureAttribute(genericSignature);
 		}
 		if (this.targetJDK >= ClassFileConstants.JDK1_5
 				&& this.referenceBinding.isNestedType()
 				&& !this.referenceBinding.isMemberType()) {
 			// add enclosing method attribute (1.5 mode only)
-			if (this.contentsOffset + 10 >= this.contents.length) {
-				resizeContents(10);
-			}
-			int enclosingMethodAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.EnclosingMethodName);
-			this.contents[this.contentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) enclosingMethodAttributeNameIndex;
-			// the length of a signature attribute is equals to 2
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 4;
-
-			int enclosingTypeIndex = this.constantPool.literalIndexForType(this.referenceBinding.enclosingType().constantPoolName());
-			this.contents[this.contentsOffset++] = (byte) (enclosingTypeIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) enclosingTypeIndex;
-			byte methodIndexByte1 = 0;
-			byte methodIndexByte2 = 0;
-			if (this.referenceBinding instanceof LocalTypeBinding) {
-				MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod;
-				if (methodBinding != null) {
-//{ObjectTeams: static role methods need to know the constant pool declaring class:
-/* orig:
-					int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this));
-  :giro */
-					int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this, this.referenceBinding));
-// SH}
-					methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
-					methodIndexByte2 = (byte) enclosingMethodIndex;
-				}
-			}
-			this.contents[this.contentsOffset++] = methodIndexByte1;
-			this.contents[this.contentsOffset++] = methodIndexByte2;
-			attributesNumber++;
+			attributesNumber += generateEnclosingMethodAttribute();
 		}
 		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
 			TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
@@ -487,20 +403,7 @@
 			for (int i = 0, max = superInterfaces.length; i < max; i++) {
 				this.missingTypes = superInterfaces[i].collectMissingTypes(this.missingTypes);
 			}
-			// add an attribute for inconsistent hierarchy
-			if (this.contentsOffset + 6 >= this.contents.length) {
-				resizeContents(6);
-			}
-			int inconsistentHierarchyNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.InconsistentHierarchy);
-			this.contents[this.contentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) inconsistentHierarchyNameIndex;
-			// the length of an inconsistent hierarchy attribute is equals to 0
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			attributesNumber++;
+			attributesNumber += generateHierarchyInconsistentAttribute();
 		}
 		// Inner class attribute
 		int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size();
@@ -514,75 +417,7 @@
 					return CharOperation.compareTo(binding1.constantPoolName(), binding2.constantPoolName());
 				}
 			});
-			// Generate the inner class attribute
-			int exSize = 8 * numberOfInnerClasses + 8;
-			if (exSize + this.contentsOffset >= this.contents.length) {
-				resizeContents(exSize);
-			}
-			// Now we now the size of the attribute and the number of entries
-			// attribute name
-			int attributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.InnerClassName);
-			this.contents[this.contentsOffset++] = (byte) (attributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) attributeNameIndex;
-			int value = (numberOfInnerClasses << 3) + 2;
-			this.contents[this.contentsOffset++] = (byte) (value >> 24);
-			this.contents[this.contentsOffset++] = (byte) (value >> 16);
-			this.contents[this.contentsOffset++] = (byte) (value >> 8);
-			this.contents[this.contentsOffset++] = (byte) value;
-			this.contents[this.contentsOffset++] = (byte) (numberOfInnerClasses >> 8);
-			this.contents[this.contentsOffset++] = (byte) numberOfInnerClasses;
-			for (int i = 0; i < numberOfInnerClasses; i++) {
-				ReferenceBinding innerClass = innerClasses[i];
-				int accessFlags = innerClass.getAccessFlags();
-//{ObjectTeams: synthetic interfaces are illegal in class files (why???):
-				if (  (accessFlags & (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
-			              == (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
-				{
-					accessFlags ^= ClassFileConstants.AccSynthetic;
-				}
-//SH}
-				int innerClassIndex = this.constantPool.literalIndexForType(innerClass.constantPoolName());
-				// inner class index
-				this.contents[this.contentsOffset++] = (byte) (innerClassIndex >> 8);
-				this.contents[this.contentsOffset++] = (byte) innerClassIndex;
-				// outer class index: anonymous and local have no outer class index
-				if (innerClass.isMemberType()) {
-					// member or member of local
-					int outerClassIndex = this.constantPool.literalIndexForType(innerClass.enclosingType().constantPoolName());
-					this.contents[this.contentsOffset++] = (byte) (outerClassIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) outerClassIndex;
-				} else {
-					// equals to 0 if the innerClass is not a member type
-					this.contents[this.contentsOffset++] = 0;
-					this.contents[this.contentsOffset++] = 0;
-				}
-				// name index
-				if (!innerClass.isAnonymousType()) {
-//{ObjectTeams: use real name not beautified version (was sourceName()).
-/* orig:
-					int nameIndex = this.constantPool.literalIndex(innerClass.sourceName());
-  :giro */
-					int nameIndex = this.constantPool.literalIndex(innerClass.internalName());
-// SH}
-
-					this.contents[this.contentsOffset++] = (byte) (nameIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) nameIndex;
-				} else {
-					// equals to 0 if the innerClass is an anonymous type
-					this.contents[this.contentsOffset++] = 0;
-					this.contents[this.contentsOffset++] = 0;
-				}
-				// access flag
-				if (innerClass.isAnonymousType()) {
-					accessFlags &= ~ClassFileConstants.AccFinal;
-				} else if (innerClass.isMemberType() && innerClass.isInterface()) {
-					accessFlags |= ClassFileConstants.AccStatic; // implicitely static
-				}
-				this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
-				this.contents[this.contentsOffset++] = (byte) accessFlags;
-			}
-			attributesNumber++;
+			attributesNumber += generateInnerClassAttribute(numberOfInnerClasses, innerClasses);
 		}
 		if (this.missingTypes != null) {
 			generateMissingTypesAttribute();
@@ -602,7 +437,6 @@
 		this.header[this.constantPoolOffset++] = (byte) (constantPoolCount >> 8);
 		this.header[this.constantPoolOffset] = (byte) constantPoolCount;
 	}
-
 	/**
 	 * INTERNAL USE-ONLY
 	 * This methods generate all the default abstract method infos that correpond to
@@ -612,10 +446,11 @@
 		MethodBinding[] defaultAbstractMethods =
 			this.referenceBinding.getDefaultAbstractMethods();
 		for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
-			generateMethodInfoHeader(defaultAbstractMethods[i]);
+			MethodBinding methodBinding = defaultAbstractMethods[i];
+			generateMethodInfoHeader(methodBinding);
 			int methodAttributeOffset = this.contentsOffset;
-			int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]);
-			completeMethodInfo(methodAttributeOffset, attributeNumber);
+			int attributeNumber = generateMethodInfoAttributes(methodBinding);
+			completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
 		}
 	}
 
@@ -625,133 +460,18 @@
 		// Generate the constantValueAttribute
 		Constant fieldConstant = fieldBinding.constant();
 		if (fieldConstant != Constant.NotAConstant){
-			if (this.contentsOffset + 8 >= this.contents.length) {
-				resizeContents(8);
-			}
-			// Now we generate the constant attribute corresponding to the fieldBinding
-			int constantValueNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.ConstantValueName);
-			this.contents[this.contentsOffset++] = (byte) (constantValueNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) constantValueNameIndex;
-			// The attribute length = 2 in case of a constantValue attribute
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 2;
-			attributesNumber++;
-			// Need to add the constant_value_index
-			switch (fieldConstant.typeID()) {
-				case T_boolean :
-					int booleanValueIndex =
-						this.constantPool.literalIndex(fieldConstant.booleanValue() ? 1 : 0);
-					this.contents[this.contentsOffset++] = (byte) (booleanValueIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) booleanValueIndex;
-					break;
-				case T_byte :
-				case T_char :
-				case T_int :
-				case T_short :
-					int integerValueIndex =
-						this.constantPool.literalIndex(fieldConstant.intValue());
-					this.contents[this.contentsOffset++] = (byte) (integerValueIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) integerValueIndex;
-					break;
-				case T_float :
-					int floatValueIndex =
-						this.constantPool.literalIndex(fieldConstant.floatValue());
-					this.contents[this.contentsOffset++] = (byte) (floatValueIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) floatValueIndex;
-					break;
-				case T_double :
-					int doubleValueIndex =
-						this.constantPool.literalIndex(fieldConstant.doubleValue());
-					this.contents[this.contentsOffset++] = (byte) (doubleValueIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) doubleValueIndex;
-					break;
-				case T_long :
-					int longValueIndex =
-						this.constantPool.literalIndex(fieldConstant.longValue());
-					this.contents[this.contentsOffset++] = (byte) (longValueIndex >> 8);
-					this.contents[this.contentsOffset++] = (byte) longValueIndex;
-					break;
-				case T_JavaLangString :
-					int stringValueIndex =
-						this.constantPool.literalIndex(
-							((StringConstant) fieldConstant).stringValue());
-					if (stringValueIndex == -1) {
-						if (!this.creatingProblemType) {
-							// report an error and abort: will lead to a problem type classfile creation
-							TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
-							FieldDeclaration[] fieldDecls = typeDeclaration.fields;
-							for (int i = 0, max = fieldDecls.length; i < max; i++) {
-								if (fieldDecls[i].binding == fieldBinding) {
-									// problem should abort
-									typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(
-										fieldDecls[i]);
-								}
-							}
-						} else {
-							// already inside a problem type creation : no constant for this field
-							this.contentsOffset = fieldAttributeOffset;
-						}
-					} else {
-						this.contents[this.contentsOffset++] = (byte) (stringValueIndex >> 8);
-						this.contents[this.contentsOffset++] = (byte) stringValueIndex;
-					}
-			}
+			attributesNumber += generateConstantValueAttribute(fieldConstant, fieldBinding, fieldAttributeOffset);
 		}
 		if (this.targetJDK < ClassFileConstants.JDK1_5 && fieldBinding.isSynthetic()) {
-			if (this.contentsOffset + 6 >= this.contents.length) {
-				resizeContents(6);
-			}
-			int syntheticAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
-			this.contents[this.contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) syntheticAttributeNameIndex;
-			// the length of a synthetic attribute is equals to 0
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			attributesNumber++;
+			attributesNumber += generateSyntheticAttribute();
 		}
 		if (fieldBinding.isDeprecated()) {
-			if (this.contentsOffset + 6 >= this.contents.length) {
-				resizeContents(6);
-			}
-			int deprecatedAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
-			this.contents[this.contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) deprecatedAttributeNameIndex;
-			// the length of a deprecated attribute is equals to 0
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			attributesNumber++;
+			attributesNumber += generateDeprecatedAttribute();
 		}
 		// add signature attribute
 		char[] genericSignature = fieldBinding.genericSignature();
 		if (genericSignature != null) {
-			// check that there is enough space to write all the bytes for the field info corresponding
-			// to the @fieldBinding
-			if (this.contentsOffset + 8 >= this.contents.length) {
-				resizeContents(8);
-			}
-			int signatureAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.SignatureName);
-			this.contents[this.contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) signatureAttributeNameIndex;
-			// the length of a signature attribute is equals to 2
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 2;
-			int signatureIndex =
-				this.constantPool.literalIndex(genericSignature);
-			this.contents[this.contentsOffset++] = (byte) (signatureIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) signatureIndex;
-			attributesNumber++;
+			attributesNumber += generateSignatureAttribute(genericSignature);
 		}
 		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
 			FieldDeclaration fieldDeclaration = fieldBinding.sourceField();
@@ -869,7 +589,7 @@
 		// always clear the strictfp/native/abstract bit for a problem method
 		generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
 		int methodAttributeOffset = this.contentsOffset;
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 
 		// Code attribute
 		attributeNumber++;
@@ -894,7 +614,7 @@
 			compilationResult.getLineSeparatorPositions(),
 			problem.getSourceLineNumber());
 
-		completeMethodInfo(methodAttributeOffset, attributeNumber);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
 	}
 
 	/**
@@ -951,6 +671,7 @@
 		this.contents[attributeOffset++] = (byte) (attributeNumber >> 8);
 		this.contents[attributeOffset] = (byte) attributeNumber;
 	}
+
 	/**
 	 * INTERNAL USE-ONLY
 	 * Generate the byte for a problem method info that correspond to a boggus constructor.
@@ -967,10 +688,10 @@
 		// always clear the strictfp/native/abstract bit for a problem method
 		generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
 		int methodAttributeOffset = this.contentsOffset;
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributesNumber = generateMethodInfoAttributes(methodBinding);
 
 		// Code attribute
-		attributeNumber++;
+		attributesNumber++;
 		int codeAttributeOffset = this.contentsOffset;
 		generateCodeAttributeHeader();
 		this.codeStream.reset(method, this);
@@ -1010,7 +731,7 @@
 				.compilationResult
 				.getLineSeparatorPositions(),
 			problemLine);
-		completeMethodInfo(methodAttributeOffset, attributeNumber);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
 	}
 	/**
 	 * INTERNAL USE-ONLY
@@ -1032,7 +753,6 @@
 		this.methodCount--; // we need to remove the method that causes the problem
 		addProblemConstructor(method, methodBinding, problems);
 	}
-
 	/**
 	 * INTERNAL USE-ONLY
 	 * Generate the byte for a problem method info that correspond to a boggus method.
@@ -1051,14 +771,14 @@
 		// always clear the strictfp/native/abstract bit for a problem method
 		generateMethodInfoHeader(methodBinding, methodBinding.modifiers & ~(ClassFileConstants.AccStrictfp | ClassFileConstants.AccNative | ClassFileConstants.AccAbstract));
 		int methodAttributeOffset = this.contentsOffset;
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributesNumber = generateMethodInfoAttributes(methodBinding);
 //{ObjectTeams: write OT-specific byte code attributes
         if (method.model != null)
-            attributeNumber += method.model.writeAttributes(this);
+            attributesNumber += method.model.writeAttributes(this);
 // SH}
 
 		// Code attribute
-		attributeNumber++;
+		attributesNumber++;
 
 		int codeAttributeOffset = this.contentsOffset;
 		generateCodeAttributeHeader();
@@ -1103,7 +823,7 @@
 				.compilationResult
 				.getLineSeparatorPositions(),
 			problemLine);
-		completeMethodInfo(methodAttributeOffset, attributeNumber);
+		completeMethodInfo(methodBinding, methodAttributeOffset, attributesNumber);
 	}
 
 	/**
@@ -1143,10 +863,11 @@
 
 		MethodBinding[] defaultAbstractMethods = this.referenceBinding.getDefaultAbstractMethods();
 		for (int i = 0, max = defaultAbstractMethods.length; i < max; i++) {
-			generateMethodInfoHeader(defaultAbstractMethods[i]);
+			MethodBinding methodBinding = defaultAbstractMethods[i];
+			generateMethodInfoHeader(methodBinding);
 			int methodAttributeOffset = this.contentsOffset;
-			int attributeNumber = generateMethodInfoAttribute(defaultAbstractMethods[i]);
-			completeMethodInfo(methodAttributeOffset, attributeNumber);
+			int attributeNumber = generateMethodInfoAttributes(methodBinding);
+			completeMethodInfo(methodBinding, methodAttributeOffset, attributeNumber);
 		}
 		// add synthetic methods infos
 		SyntheticMethodBinding[] syntheticMethods = this.referenceBinding.syntheticMethods();
@@ -1206,7 +927,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1236,7 +957,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1266,7 +987,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1297,7 +1018,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1328,7 +1049,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1358,7 +1079,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1386,7 +1107,7 @@
 		generateMethodInfoHeader(methodBinding);
 		int methodAttributeOffset = this.contentsOffset;
 		// this will add exception attribute, synthetic attribute, deprecated attribute,...
-		int attributeNumber = generateMethodInfoAttribute(methodBinding);
+		int attributeNumber = generateMethodInfoAttributes(methodBinding);
 		// Code attribute
 		int codeAttributeOffset = this.contentsOffset;
 		attributeNumber++; // add code attribute
@@ -1470,7 +1191,7 @@
 							Messages.bind(Messages.abort_invalidExceptionAttribute, new String(this.codeStream.methodDeclaration.selector)),
 							this.codeStream.methodDeclaration);
 				}
-				while  (iRange < maxRange) {
+				while (iRange < maxRange) {
 					int start = exceptionLabel.ranges[iRange++]; // even ranges are start positions
 					this.contents[localContentsOffset++] = (byte) (start >> 8);
 					this.contents[localContentsOffset++] = (byte) start;
@@ -1505,752 +1226,52 @@
 		}
 		// debug attributes
 		int codeAttributeAttributeOffset = localContentsOffset;
-		int attributeNumber = 0;
+		int attributesNumber = 0;
 		// leave two bytes for the attribute_length
 		localContentsOffset += 2;
 		if (localContentsOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
 
+		this.contentsOffset = localContentsOffset;
+
 		// first we handle the linenumber attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
-			/* Create and add the line number attribute (used for debugging)
-			 * Build the pairs of:
-			 * 	(bytecodePC lineNumber)
-			 * according to the table of start line indexes and the pcToSourceMap table
-			 * contained into the codestream
-			 */
-			int[] pcToSourceMapTable;
-			if (((pcToSourceMapTable = this.codeStream.pcToSourceMap) != null)
-				&& (this.codeStream.pcToSourceMapSize != 0)) {
-				int lineNumberNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
-				if (localContentsOffset + 8 >= this.contents.length) {
-					resizeContents(8);
-				}
-				this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
-				int lineNumberTableOffset = localContentsOffset;
-				localContentsOffset += 6;
-				// leave space for attribute_length and line_number_table_length
-				int numberOfEntries = 0;
-				int length = this.codeStream.pcToSourceMapSize;
-				for (int i = 0; i < length;) {
-					// write the entry
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int pc = pcToSourceMapTable[i++];
-					this.contents[localContentsOffset++] = (byte) (pc >> 8);
-					this.contents[localContentsOffset++] = (byte) pc;
-					int lineNumber = pcToSourceMapTable[i++];
-					this.contents[localContentsOffset++] = (byte) (lineNumber >> 8);
-					this.contents[localContentsOffset++] = (byte) lineNumber;
-					numberOfEntries++;
-				}
-				// now we change the size of the line number attribute
-				int lineNumberAttr_length = numberOfEntries * 4 + 2;
-				this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
-				this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
-				this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
-				this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
-				this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
-				this.contents[lineNumberTableOffset++] = (byte) numberOfEntries;
-				attributeNumber++;
-			}
+			attributesNumber += generateLineNumberAttribute();
 		}
 		// then we do the local variable attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
-			int numberOfEntries = 0;
-			int localVariableNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
 			final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration.isStatic();
-			int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0 : 1);
-			for (int i = 0; i < this.codeStream.allLocalsCounter; i++) {
-				LocalVariableBinding localVariableBinding = this.codeStream.locals[i];
-				maxOfEntries += 10 * localVariableBinding.initializationCount;
-			}
-			// reserve enough space
-			if (localContentsOffset + maxOfEntries >= this.contents.length) {
-				resizeContents(maxOfEntries);
-			}
-			this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
-			int localVariableTableOffset = localContentsOffset;
-			// leave space for attribute_length and local_variable_table_length
-			localContentsOffset += 6;
-			int nameIndex;
-			int descriptorIndex;
-			SourceTypeBinding declaringClassBinding = null;
-			if (!methodDeclarationIsStatic) {
-				numberOfEntries++;
-				this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
-				this.contents[localContentsOffset++] = 0;
-				this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-				this.contents[localContentsOffset++] = (byte) code_length;
-				nameIndex = this.constantPool.literalIndex(ConstantPool.This);
-				this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) nameIndex;
-				declaringClassBinding = (SourceTypeBinding) this.codeStream.methodDeclaration.binding.declaringClass;
-				descriptorIndex =
-					this.constantPool.literalIndex(
-						declaringClassBinding.signature());
-				this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) descriptorIndex;
-				this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
-				this.contents[localContentsOffset++] = 0;
-			}
-			// used to remember the local variable with a generic type
-			int genericLocalVariablesCounter = 0;
-			LocalVariableBinding[] genericLocalVariables = null;
-			int numberOfGenericEntries = 0;
-
-			for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
-				LocalVariableBinding localVariable = this.codeStream.locals[i];
-				if (localVariable.declaration == null) continue;
-				final TypeBinding localVariableTypeBinding = localVariable.type;
-				boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable();
-				if (localVariable.initializationCount != 0 && isParameterizedType) {
-					if (genericLocalVariables == null) {
-						// we cannot have more than max locals
-						genericLocalVariables = new LocalVariableBinding[max];
-					}
-					genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
-				}
-				for (int j = 0; j < localVariable.initializationCount; j++) {
-					int startPC = localVariable.initializationPCs[j << 1];
-					int endPC = localVariable.initializationPCs[(j << 1) + 1];
-					if (startPC != endPC) { // only entries for non zero length
-						if (endPC == -1) {
-							localVariable.declaringScope.problemReporter().abortDueToInternalError(
-									Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)),
-									(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
-						}
-						if (isParameterizedType) {
-							numberOfGenericEntries++;
-						}
-						// now we can safely add the local entry
-						numberOfEntries++;
-						this.contents[localContentsOffset++] = (byte) (startPC >> 8);
-						this.contents[localContentsOffset++] = (byte) startPC;
-						int length = endPC - startPC;
-						this.contents[localContentsOffset++] = (byte) (length >> 8);
-						this.contents[localContentsOffset++] = (byte) length;
-						nameIndex = this.constantPool.literalIndex(localVariable.name);
-						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-						this.contents[localContentsOffset++] = (byte) nameIndex;
-						descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
-						this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-						this.contents[localContentsOffset++] = (byte) descriptorIndex;
-						int resolvedPosition = localVariable.resolvedPosition;
-						this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-						this.contents[localContentsOffset++] = (byte) resolvedPosition;
-					}
-				}
-			}
-			int value = numberOfEntries * 10 + 2;
-			this.contents[localVariableTableOffset++] = (byte) (value >> 24);
-			this.contents[localVariableTableOffset++] = (byte) (value >> 16);
-			this.contents[localVariableTableOffset++] = (byte) (value >> 8);
-			this.contents[localVariableTableOffset++] = (byte) value;
-			this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
-			this.contents[localVariableTableOffset] = (byte) numberOfEntries;
-			attributeNumber++;
-
-			final boolean currentInstanceIsGeneric =
-				!methodDeclarationIsStatic
-				&& declaringClassBinding != null
-				&& declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
-			if (genericLocalVariablesCounter != 0 || currentInstanceIsGeneric) {
-				// add the local variable type table attribute
-				numberOfGenericEntries += (currentInstanceIsGeneric ? 1 : 0);
-				maxOfEntries = 8 + numberOfGenericEntries * 10;
-				// reserve enough space
-				if (localContentsOffset + maxOfEntries >= this.contents.length) {
-					resizeContents(maxOfEntries);
-				}
-				int localVariableTypeNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
-				this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
-				value = numberOfGenericEntries * 10 + 2;
-				this.contents[localContentsOffset++] = (byte) (value >> 24);
-				this.contents[localContentsOffset++] = (byte) (value >> 16);
-				this.contents[localContentsOffset++] = (byte) (value >> 8);
-				this.contents[localContentsOffset++] = (byte) value;
-				this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
-				this.contents[localContentsOffset++] = (byte) numberOfGenericEntries;
-				if (currentInstanceIsGeneric) {
-					this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
-					this.contents[localContentsOffset++] = 0;
-					this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-					this.contents[localContentsOffset++] = (byte) code_length;
-					nameIndex = this.constantPool.literalIndex(ConstantPool.This);
-					this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) nameIndex;
-					descriptorIndex = this.constantPool.literalIndex(declaringClassBinding.genericTypeSignature());
-					this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) descriptorIndex;
-					this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
-					this.contents[localContentsOffset++] = 0;
-				}
-
-				for (int i = 0; i < genericLocalVariablesCounter; i++) {
-					LocalVariableBinding localVariable = genericLocalVariables[i];
-					for (int j = 0; j < localVariable.initializationCount; j++) {
-						int startPC = localVariable.initializationPCs[j << 1];
-						int endPC = localVariable.initializationPCs[(j << 1) + 1];
-						if (startPC != endPC) {
-							// only entries for non zero length
-							// now we can safely add the local entry
-							this.contents[localContentsOffset++] = (byte) (startPC >> 8);
-							this.contents[localContentsOffset++] = (byte) startPC;
-							int length = endPC - startPC;
-							this.contents[localContentsOffset++] = (byte) (length >> 8);
-							this.contents[localContentsOffset++] = (byte) length;
-							nameIndex = this.constantPool.literalIndex(localVariable.name);
-							this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) nameIndex;
-							descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
-							this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) descriptorIndex;
-							int resolvedPosition = localVariable.resolvedPosition;
-							this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-							this.contents[localContentsOffset++] = (byte) resolvedPosition;
-						}
-					}
-				}
-				attributeNumber++;
-			}
+			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
 		}
 
 		if (addStackMaps) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapTableAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
-					this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
-					int stackMapTableAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					StackMapFrame prevFrame = null;
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						prevFrame = currentFrame;
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
-						switch (currentFrame.getFrameType(prevFrame)) {
-							case StackMapFrame.APPEND_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
-								int numberOfLocals = currentFrame.getNumberOfLocals();
-								for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
-									if (localContentsOffset + 6 >= this.contents.length) {
-										resizeContents(6);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfDifferentLocals--;
-									}
-								}
-								break;
-							case StackMapFrame.SAME_FRAME :
-								if (localContentsOffset + 1 >= this.contents.length) {
-									resizeContents(1);
-								}
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_FRAME_EXTENDED :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								this.contents[localContentsOffset++] = (byte) 251;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.CHOP_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
-								if (localContentsOffset + 6 >= this.contents.length) {
-									resizeContents(6);
-								}
-								this.contents[localContentsOffset++] = (byte) 247;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							default :
-								// FULL_FRAME
-								if (localContentsOffset + 5 >= this.contents.length) {
-									resizeContents(5);
-								}
-								this.contents[localContentsOffset++] = (byte) 255;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int numberOfLocalOffset = localContentsOffset;
-								localContentsOffset += 2; // leave two spots for number of locals
-								int numberOfLocalEntries = 0;
-								numberOfLocals = currentFrame.getNumberOfLocals();
-								int numberOfEntries = 0;
-								int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-								for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfLocalEntries++;
-									}
-									numberOfEntries++;
-								}
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-								this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-								int numberOfStackItems = currentFrame.numberOfStackItems;
-								this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-								this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-								for (int i = 0; i < numberOfStackItems; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.stackItems[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-									}
-								}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapTableAttribute(
+					this.codeStream.methodDeclaration.binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
-					this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
-					int stackMapAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int frameOffset = currentFrame.pc;
-						// FULL_FRAME
-						if (localContentsOffset + 5 >= this.contents.length) {
-							resizeContents(5);
-						}
-						this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
-						this.contents[localContentsOffset++] = (byte) frameOffset;
-						int numberOfLocalOffset = localContentsOffset;
-						localContentsOffset += 2; // leave two spots for number of locals
-						int numberOfLocalEntries = 0;
-						int numberOfLocals = currentFrame.getNumberOfLocals();
-						int numberOfEntries = 0;
-						int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-						for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.locals[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										i++;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										i++;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-								numberOfLocalEntries++;
-							}
-							numberOfEntries++;
-						}
-						if (localContentsOffset + 4 >= this.contents.length) {
-							resizeContents(4);
-						}
-						this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-						this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-						int numberOfStackItems = currentFrame.numberOfStackItems;
-						this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-						this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-						for (int i = 0; i < numberOfStackItems; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.stackItems[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-							}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapAttribute(
+					this.codeStream.methodDeclaration.binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
-		this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
 
 		// update the attribute length
-		int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
+		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
 		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
 		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
 		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
 		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-		this.contentsOffset = localContentsOffset;
 	}
 
 	/**
@@ -2351,703 +1372,40 @@
 		}
 		// debug attributes
 		int codeAttributeAttributeOffset = localContentsOffset;
-		int attributeNumber = 0;
+		int attributesNumber = 0;
 		// leave two bytes for the attribute_length
 		localContentsOffset += 2;
 		if (localContentsOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
 
+		this.contentsOffset = localContentsOffset;
+
 		// first we handle the linenumber attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
-			/* Create and add the line number attribute (used for debugging)
-			 * Build the pairs of:
-			 * 	(bytecodePC lineNumber)
-			 * according to the table of start line indexes and the pcToSourceMap table
-			 * contained into the codestream
-			 */
-			int[] pcToSourceMapTable;
-			if (((pcToSourceMapTable = this.codeStream.pcToSourceMap) != null)
-				&& (this.codeStream.pcToSourceMapSize != 0)) {
-				int lineNumberNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
-				if (localContentsOffset + 8 >= this.contents.length) {
-					resizeContents(8);
-				}
-				this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
-				int lineNumberTableOffset = localContentsOffset;
-				localContentsOffset += 6;
-				// leave space for attribute_length and line_number_table_length
-				int numberOfEntries = 0;
-				int length = this.codeStream.pcToSourceMapSize;
-				for (int i = 0; i < length;) {
-					// write the entry
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int pc = pcToSourceMapTable[i++];
-					this.contents[localContentsOffset++] = (byte) (pc >> 8);
-					this.contents[localContentsOffset++] = (byte) pc;
-					int lineNumber = pcToSourceMapTable[i++];
-					this.contents[localContentsOffset++] = (byte) (lineNumber >> 8);
-					this.contents[localContentsOffset++] = (byte) lineNumber;
-					numberOfEntries++;
-				}
-				// now we change the size of the line number attribute
-				int lineNumberAttr_length = numberOfEntries * 4 + 2;
-				this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
-				this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
-				this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
-				this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
-				this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
-				this.contents[lineNumberTableOffset++] = (byte) numberOfEntries;
-				attributeNumber++;
-			}
+			attributesNumber += generateLineNumberAttribute();
 		}
 		// then we do the local variable attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
-			int numberOfEntries = 0;
-			//		codeAttribute.addLocalVariableTableAttribute(this);
-			if ((this.codeStream.pcToSourceMap != null)
-				&& (this.codeStream.pcToSourceMapSize != 0)) {
-				int localVariableNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
-				if (localContentsOffset + 8 >= this.contents.length) {
-					resizeContents(8);
-				}
-				this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
-				int localVariableTableOffset = localContentsOffset;
-				localContentsOffset += 6;
-
-				// leave space for attribute_length and local_variable_table_length
-				int nameIndex;
-				int descriptorIndex;
-
-				// used to remember the local variable with a generic type
-				int genericLocalVariablesCounter = 0;
-				LocalVariableBinding[] genericLocalVariables = null;
-				int numberOfGenericEntries = 0;
-
-				for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
-					LocalVariableBinding localVariable = this.codeStream.locals[i];
-					if (localVariable.declaration == null) continue;
-					final TypeBinding localVariableTypeBinding = localVariable.type;
-					boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable();
-					if (localVariable.initializationCount != 0 && isParameterizedType) {
-						if (genericLocalVariables == null) {
-							// we cannot have more than max locals
-							genericLocalVariables = new LocalVariableBinding[max];
-						}
-						genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
-					}
-					for (int j = 0; j < localVariable.initializationCount; j++) {
-						int startPC = localVariable.initializationPCs[j << 1];
-						int endPC = localVariable.initializationPCs[(j << 1) + 1];
-						if (startPC != endPC) { // only entries for non zero length
-							if (endPC == -1) {
-								localVariable.declaringScope.problemReporter().abortDueToInternalError(
-									Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)),
-									(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
-							}
-							if (localContentsOffset + 10 >= this.contents.length) {
-								resizeContents(10);
-							}
-							// now we can safely add the local entry
-							numberOfEntries++;
-							if (isParameterizedType) {
-								numberOfGenericEntries++;
-							}
-							this.contents[localContentsOffset++] = (byte) (startPC >> 8);
-							this.contents[localContentsOffset++] = (byte) startPC;
-							int length = endPC - startPC;
-							this.contents[localContentsOffset++] = (byte) (length >> 8);
-							this.contents[localContentsOffset++] = (byte) length;
-							nameIndex = this.constantPool.literalIndex(localVariable.name);
-							this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) nameIndex;
-							descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
-							this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) descriptorIndex;
-							int resolvedPosition = localVariable.resolvedPosition;
-							this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-							this.contents[localContentsOffset++] = (byte) resolvedPosition;
-						}
-					}
-				}
-				int value = numberOfEntries * 10 + 2;
-				this.contents[localVariableTableOffset++] = (byte) (value >> 24);
-				this.contents[localVariableTableOffset++] = (byte) (value >> 16);
-				this.contents[localVariableTableOffset++] = (byte) (value >> 8);
-				this.contents[localVariableTableOffset++] = (byte) value;
-				this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
-				this.contents[localVariableTableOffset] = (byte) numberOfEntries;
-				attributeNumber++;
-
-				if (genericLocalVariablesCounter != 0) {
-					// add the local variable type table attribute
-					// reserve enough space
-					int maxOfEntries = 8 + numberOfGenericEntries * 10;
-
-					if (localContentsOffset + maxOfEntries >= this.contents.length) {
-						resizeContents(maxOfEntries);
-					}
-					int localVariableTypeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
-					this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
-					value = numberOfGenericEntries * 10 + 2;
-					this.contents[localContentsOffset++] = (byte) (value >> 24);
-					this.contents[localContentsOffset++] = (byte) (value >> 16);
-					this.contents[localContentsOffset++] = (byte) (value >> 8);
-					this.contents[localContentsOffset++] = (byte) value;
-					this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
-					this.contents[localContentsOffset++] = (byte) numberOfGenericEntries;
-					for (int i = 0; i < genericLocalVariablesCounter; i++) {
-						LocalVariableBinding localVariable = genericLocalVariables[i];
-						for (int j = 0; j < localVariable.initializationCount; j++) {
-							int startPC = localVariable.initializationPCs[j << 1];
-							int endPC = localVariable.initializationPCs[(j << 1) + 1];
-							if (startPC != endPC) { // only entries for non zero length
-								// now we can safely add the local entry
-								this.contents[localContentsOffset++] = (byte) (startPC >> 8);
-								this.contents[localContentsOffset++] = (byte) startPC;
-								int length = endPC - startPC;
-								this.contents[localContentsOffset++] = (byte) (length >> 8);
-								this.contents[localContentsOffset++] = (byte) length;
-								nameIndex = this.constantPool.literalIndex(localVariable.name);
-								this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-								this.contents[localContentsOffset++] = (byte) nameIndex;
-								descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
-								this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-								this.contents[localContentsOffset++] = (byte) descriptorIndex;
-								int resolvedPosition = localVariable.resolvedPosition;
-								this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-								this.contents[localContentsOffset++] = (byte) resolvedPosition;
-							}
-						}
-					}
-					attributeNumber++;
-				}
-			}
+			attributesNumber += generateLocalVariableTableAttribute(code_length, true, false);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(null, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, true);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapTableAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
-					this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
-					int stackMapTableAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					StackMapFrame prevFrame = null;
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						prevFrame = currentFrame;
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
-						switch (currentFrame.getFrameType(prevFrame)) {
-							case StackMapFrame.APPEND_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
-								int numberOfLocals = currentFrame.getNumberOfLocals();
-								for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
-									if (localContentsOffset + 6 >= this.contents.length) {
-										resizeContents(6);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfDifferentLocals--;
-									}
-								}
-								break;
-							case StackMapFrame.SAME_FRAME :
-								if (localContentsOffset + 1 >= this.contents.length) {
-									resizeContents(1);
-								}
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_FRAME_EXTENDED :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								this.contents[localContentsOffset++] = (byte) 251;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.CHOP_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
-								if (localContentsOffset + 6 >= this.contents.length) {
-									resizeContents(6);
-								}
-								this.contents[localContentsOffset++] = (byte) 247;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							default :
-								// FULL_FRAME
-								if (localContentsOffset + 5 >= this.contents.length) {
-									resizeContents(5);
-								}
-								this.contents[localContentsOffset++] = (byte) 255;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int numberOfLocalOffset = localContentsOffset;
-								localContentsOffset += 2; // leave two spots for number of locals
-								int numberOfLocalEntries = 0;
-								numberOfLocals = currentFrame.getNumberOfLocals();
-								int numberOfEntries = 0;
-								int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-								for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfLocalEntries++;
-									}
-									numberOfEntries++;
-								}
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-								this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-								int numberOfStackItems = currentFrame.numberOfStackItems;
-								this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-								this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-								for (int i = 0; i < numberOfStackItems; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.stackItems[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-									}
-								}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapTableAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
-					this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
-					int stackMapAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int frameOffset = currentFrame.pc;
-						// FULL_FRAME
-						if (localContentsOffset + 5 >= this.contents.length) {
-							resizeContents(5);
-						}
-						this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
-						this.contents[localContentsOffset++] = (byte) frameOffset;
-						int numberOfLocalOffset = localContentsOffset;
-						localContentsOffset += 2; // leave two spots for number of locals
-						int numberOfLocalEntries = 0;
-						int numberOfLocals = currentFrame.getNumberOfLocals();
-						int numberOfEntries = 0;
-						int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-						for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.locals[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										i++;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										i++;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-								numberOfLocalEntries++;
-							}
-							numberOfEntries++;
-						}
-						if (localContentsOffset + 4 >= this.contents.length) {
-							resizeContents(4);
-						}
-						this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-						this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-						int numberOfStackItems = currentFrame.numberOfStackItems;
-						this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-						this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-						for (int i = 0; i < numberOfStackItems; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.stackItems[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-							}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
 		}
 
 		// update the number of attributes
@@ -3055,15 +1413,14 @@
 		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
-		this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
 		// update the attribute length
-		int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
+		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
 		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
 		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
 		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
 		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-		this.contentsOffset = localContentsOffset;
 	}
 
 	/**
@@ -3077,8 +1434,8 @@
 	 * - and debug attributes if necessary.
 	 */
 	public void completeCodeAttributeForClinit(
-		int codeAttributeOffset,
-		int problemLine) {
+			int codeAttributeOffset,
+			int problemLine) {
 		// reinitialize the contents with the byte modified by the code stream
 		this.contents = this.codeStream.bCodeStream;
 		int localContentsOffset = this.codeStream.classFileOffset;
@@ -3111,41 +1468,18 @@
 
 		// debug attributes
 		int codeAttributeAttributeOffset = localContentsOffset;
-		int attributeNumber = 0; // leave two bytes for the attribute_length
+		int attributesNumber = 0; // leave two bytes for the attribute_length
 		localContentsOffset += 2; // first we handle the linenumber attribute
 		if (localContentsOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
 
+		this.contentsOffset = localContentsOffset;
 		// first we handle the linenumber attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
-			if (localContentsOffset + 20 >= this.contents.length) {
-				resizeContents(20);
-			}
-			/* Create and add the line number attribute (used for debugging)
-				* Build the pairs of:
-				* (bytecodePC lineNumber)
-				* according to the table of start line indexes and the pcToSourceMap table
-				* contained into the codestream
-				*/
-			int lineNumberNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
-			this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 6;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 1;
-			// first entry at pc = 0
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = (byte) (problemLine >> 8);
-			this.contents[localContentsOffset++] = (byte) problemLine;
-			// now we change the size of the line number attribute
-			attributeNumber++;
+			attributesNumber += generateLineNumberAttribute(problemLine);
 		}
+		localContentsOffset = this.contentsOffset;
 		// then we do the local variable attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
 			int localVariableNameIndex =
@@ -3161,525 +1495,27 @@
 			this.contents[localContentsOffset++] = 2;
 			this.contents[localContentsOffset++] = 0;
 			this.contents[localContentsOffset++] = 0;
-			attributeNumber++;
+			attributesNumber++;
 		}
 
+		this.contentsOffset = localContentsOffset;
+
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(null, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, true);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapTableAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
-					this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
-					int stackMapTableAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					numberOfFrames = 0;
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					StackMapFrame prevFrame = null;
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						prevFrame = currentFrame;
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						numberOfFrames++;
-						int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
-						switch (currentFrame.getFrameType(prevFrame)) {
-							case StackMapFrame.APPEND_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
-								int numberOfLocals = currentFrame.getNumberOfLocals();
-								for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
-									if (localContentsOffset + 6 >= this.contents.length) {
-										resizeContents(6);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfDifferentLocals--;
-									}
-								}
-								break;
-							case StackMapFrame.SAME_FRAME :
-								if (localContentsOffset + 1 >= this.contents.length) {
-									resizeContents(1);
-								}
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_FRAME_EXTENDED :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								this.contents[localContentsOffset++] = (byte) 251;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.CHOP_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
-								if (localContentsOffset + 6 >= this.contents.length) {
-									resizeContents(6);
-								}
-								this.contents[localContentsOffset++] = (byte) 247;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							default :
-								// FULL_FRAME
-								if (localContentsOffset + 5 >= this.contents.length) {
-									resizeContents(5);
-								}
-								this.contents[localContentsOffset++] = (byte) 255;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int numberOfLocalOffset = localContentsOffset;
-								localContentsOffset += 2; // leave two spots for number of locals
-								int numberOfLocalEntries = 0;
-								numberOfLocals = currentFrame.getNumberOfLocals();
-								int numberOfEntries = 0;
-								int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-								for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfLocalEntries++;
-									}
-									numberOfEntries++;
-								}
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-								this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-								int numberOfStackItems = currentFrame.numberOfStackItems;
-								this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-								this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-								for (int i = 0; i < numberOfStackItems; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.stackItems[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-									}
-								}
-						}
-					}
-
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapTableAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
-					this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
-					int stackMapAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int frameOffset = currentFrame.pc;
-						// FULL_FRAME
-						if (localContentsOffset + 5 >= this.contents.length) {
-							resizeContents(5);
-						}
-						this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
-						this.contents[localContentsOffset++] = (byte) frameOffset;
-						int numberOfLocalOffset = localContentsOffset;
-						localContentsOffset += 2; // leave two spots for number of locals
-						int numberOfLocalEntries = 0;
-						int numberOfLocals = currentFrame.getNumberOfLocals();
-						int numberOfEntries = 0;
-						int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-						for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.locals[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										i++;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										i++;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-								numberOfLocalEntries++;
-							}
-							numberOfEntries++;
-						}
-						if (localContentsOffset + 4 >= this.contents.length) {
-							resizeContents(4);
-						}
-						this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-						this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-						int numberOfStackItems = currentFrame.numberOfStackItems;
-						this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-						this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-						for (int i = 0; i < numberOfStackItems; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.stackItems[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-							}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapAttribute(
+					null,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					true);
 		}
 
 		// update the number of attributes
@@ -3687,25 +1523,25 @@
 		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
-		this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
 		// update the attribute length
-		int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
+		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
 		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
 		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
 		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
 		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-		this.contentsOffset = localContentsOffset;
 	}
 
+
 	/**
 	 *
 	 */
 	public void completeCodeAttributeForMissingAbstractProblemMethod(
-		MethodBinding binding,
-		int codeAttributeOffset,
-		int[] startLineIndexes,
-		int problemLine) {
+			MethodBinding binding,
+			int codeAttributeOffset,
+			int[] startLineIndexes,
+			int problemLine) {
 		// reinitialize the localContents with the byte modified by the code stream
 		this.contents = this.codeStream.bCodeStream;
 		int localContentsOffset = this.codeStream.classFileOffset;
@@ -3729,560 +1565,36 @@
 		this.contents[localContentsOffset++] = 0;
 		// debug attributes
 		int codeAttributeAttributeOffset = localContentsOffset;
-		int attributeNumber = 0; // leave two bytes for the attribute_length
+		int attributesNumber = 0; // leave two bytes for the attribute_length
 		localContentsOffset += 2; // first we handle the linenumber attribute
 		if (localContentsOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
 
+		this.contentsOffset = localContentsOffset;
 		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
-			if (localContentsOffset + 12 >= this.contents.length) {
-				resizeContents(12);
-			}
-			/* Create and add the line number attribute (used for debugging)
-				* Build the pairs of:
-				* (bytecodePC lineNumber)
-				* according to the table of start line indexes and the pcToSourceMap table
-				* contained into the codestream
-				*/
-			int lineNumberNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
-			this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 6;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 1;
 			if (problemLine == 0) {
 				problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
 			}
-			// first entry at pc = 0
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = (byte) (problemLine >> 8);
-			this.contents[localContentsOffset++] = (byte) problemLine;
-			// now we change the size of the line number attribute
-			attributeNumber++;
+			attributesNumber += generateLineNumberAttribute(problemLine);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapTableAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
-					this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
-					int stackMapTableAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					numberOfFrames = 0;
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					StackMapFrame prevFrame = null;
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						prevFrame = currentFrame;
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						numberOfFrames++;
-						int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
-						switch (currentFrame.getFrameType(prevFrame)) {
-							case StackMapFrame.APPEND_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
-								int numberOfLocals = currentFrame.getNumberOfLocals();
-								for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
-									if (localContentsOffset + 6 >= this.contents.length) {
-										resizeContents(6);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfDifferentLocals--;
-									}
-								}
-								break;
-							case StackMapFrame.SAME_FRAME :
-								if (localContentsOffset + 1 >= this.contents.length) {
-									resizeContents(1);
-								}
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_FRAME_EXTENDED :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								this.contents[localContentsOffset++] = (byte) 251;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.CHOP_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
-								if (localContentsOffset + 6 >= this.contents.length) {
-									resizeContents(6);
-								}
-								this.contents[localContentsOffset++] = (byte) 247;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							default :
-								// FULL_FRAME
-								if (localContentsOffset + 5 >= this.contents.length) {
-									resizeContents(5);
-								}
-								this.contents[localContentsOffset++] = (byte) 255;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int numberOfLocalOffset = localContentsOffset;
-								localContentsOffset += 2; // leave two spots for number of locals
-								int numberOfLocalEntries = 0;
-								numberOfLocals = currentFrame.getNumberOfLocals();
-								int numberOfEntries = 0;
-								int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-								for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfLocalEntries++;
-									}
-									numberOfEntries++;
-								}
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-								this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-								int numberOfStackItems = currentFrame.numberOfStackItems;
-								this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-								this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-								for (int i = 0; i < numberOfStackItems; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.stackItems[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-									}
-								}
-						}
-					}
-
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapTableAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
-					this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
-					int stackMapAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int frameOffset = currentFrame.pc;
-						// FULL_FRAME
-						if (localContentsOffset + 5 >= this.contents.length) {
-							resizeContents(5);
-						}
-						this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
-						this.contents[localContentsOffset++] = (byte) frameOffset;
-						int numberOfLocalOffset = localContentsOffset;
-						localContentsOffset += 2; // leave two spots for number of locals
-						int numberOfLocalEntries = 0;
-						int numberOfLocals = currentFrame.getNumberOfLocals();
-						int numberOfEntries = 0;
-						int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-						for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.locals[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										i++;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										i++;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-								numberOfLocalEntries++;
-							}
-							numberOfEntries++;
-						}
-						if (localContentsOffset + 4 >= this.contents.length) {
-							resizeContents(4);
-						}
-						this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-						this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-						int numberOfStackItems = currentFrame.numberOfStackItems;
-						this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-						this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-						for (int i = 0; i < numberOfStackItems; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.stackItems[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-							}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
 		// then we do the local variable attribute
@@ -4290,15 +1602,14 @@
 		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
-		this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
 		// update the attribute length
-		int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
+		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
 		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
 		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
 		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
 		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-		this.contentsOffset = localContentsOffset;
 	}
 
 	/**
@@ -4313,7 +1624,12 @@
 	 *
 	 * @param codeAttributeOffset <CODE>int</CODE>
 	 */
-	public void completeCodeAttributeForProblemMethod(AbstractMethodDeclaration method, MethodBinding binding, int codeAttributeOffset, int[] startLineIndexes, int problemLine) {
+	public void completeCodeAttributeForProblemMethod(
+			AbstractMethodDeclaration method,
+			MethodBinding binding,
+			int codeAttributeOffset,
+			int[] startLineIndexes,
+			int problemLine) {
 		// reinitialize the localContents with the byte modified by the code stream
 		this.contents = this.codeStream.bCodeStream;
 		int localContentsOffset = this.codeStream.classFileOffset;
@@ -4339,800 +1655,56 @@
 		this.contents[localContentsOffset++] = 0;
 		// debug attributes
 		int codeAttributeAttributeOffset = localContentsOffset;
-		int attributeNumber = 0; // leave two bytes for the attribute_length
+		int attributesNumber = 0; // leave two bytes for the attribute_length
 		localContentsOffset += 2; // first we handle the linenumber attribute
 		if (localContentsOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
 
+		this.contentsOffset = localContentsOffset;
 		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
-			if (localContentsOffset + 20 >= this.contents.length) {
-				resizeContents(20);
-			}
-			/* Create and add the line number attribute (used for debugging)
-				* Build the pairs of:
-				* (bytecodePC lineNumber)
-				* according to the table of start line indexes and the pcToSourceMap table
-				* contained into the codestream
-				*/
-			int lineNumberNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
-			this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 6;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 1;
 			if (problemLine == 0) {
 				problemLine = Util.getLineNumber(binding.sourceStart(), startLineIndexes, 0, startLineIndexes.length-1);
 			}
-			// first entry at pc = 0
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = (byte) (problemLine >> 8);
-			this.contents[localContentsOffset++] = (byte) problemLine;
-			// now we change the size of the line number attribute
-			attributeNumber++;
+			attributesNumber += generateLineNumberAttribute(problemLine);
 		}
+
 		// then we do the local variable attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
-			// compute the resolved position for the arguments of the method
-			int argSize;
-			int numberOfEntries = 0;
-			//		codeAttribute.addLocalVariableTableAttribute(this);
-			int localVariableNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
-			if (localContentsOffset + 8 >= this.contents.length) {
-				resizeContents(8);
-			}
-			this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
-			int localVariableTableOffset = localContentsOffset;
-			localContentsOffset += 6;
-			// leave space for attribute_length and local_variable_table_length
-			int descriptorIndex;
-			int nameIndex;
-			SourceTypeBinding declaringClassBinding = null;
 			final boolean methodDeclarationIsStatic = this.codeStream.methodDeclaration.isStatic();
-			if (!methodDeclarationIsStatic) {
-				numberOfEntries++;
-				if (localContentsOffset + 10 >= this.contents.length) {
-					resizeContents(10);
-				}
-				this.contents[localContentsOffset++] = 0;
-				this.contents[localContentsOffset++] = 0;
-				this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-				this.contents[localContentsOffset++] = (byte) code_length;
-				nameIndex = this.constantPool.literalIndex(ConstantPool.This);
-				this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) nameIndex;
-				declaringClassBinding = (SourceTypeBinding) this.codeStream.methodDeclaration.binding.declaringClass;
-				descriptorIndex =
-					this.constantPool.literalIndex(declaringClassBinding.signature());
-				this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) descriptorIndex;
-				// the resolved position for this is always 0
-				this.contents[localContentsOffset++] = 0;
-				this.contents[localContentsOffset++] = 0;
-			}
-			// used to remember the local variable with a generic type
-			int genericLocalVariablesCounter = 0;
-			LocalVariableBinding[] genericLocalVariables = null;
-			int numberOfGenericEntries = 0;
-
-			if (binding.isConstructor()) {
-				ReferenceBinding declaringClass = binding.declaringClass;
-				if (declaringClass.isNestedType()) {
-					NestedTypeBinding methodDeclaringClass = (NestedTypeBinding) declaringClass;
-					argSize = methodDeclaringClass.getEnclosingInstancesSlotSize();
-					SyntheticArgumentBinding[] syntheticArguments;
-					if ((syntheticArguments = methodDeclaringClass.syntheticEnclosingInstances()) != null) {
-						for (int i = 0, max = syntheticArguments.length; i < max; i++) {
-							LocalVariableBinding localVariable = syntheticArguments[i];
-							final TypeBinding localVariableTypeBinding = localVariable.type;
-							if (localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable()) {
-								if (genericLocalVariables == null) {
-									// we cannot have more than max locals
-									genericLocalVariables = new LocalVariableBinding[max];
-								}
-								genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
-								numberOfGenericEntries++;
-							}
-							if (localContentsOffset + 10 >= this.contents.length) {
-								resizeContents(10);
-							}
-							// now we can safely add the local entry
-							numberOfEntries++;
-							this.contents[localContentsOffset++] = 0;
-							this.contents[localContentsOffset++] = 0;
-							this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-							this.contents[localContentsOffset++] = (byte) code_length;
-							nameIndex = this.constantPool.literalIndex(localVariable.name);
-							this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) nameIndex;
-							descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
-							this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) descriptorIndex;
-							int resolvedPosition = localVariable.resolvedPosition;
-							this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-							this.contents[localContentsOffset++] = (byte) resolvedPosition;
-						}
-					}
-				} else {
-					argSize = 1;
-				}
-			} else {
-				argSize = binding.isStatic() ? 0 : 1;
-			}
-
-			int genericArgumentsCounter = 0;
-			int[] genericArgumentsNameIndexes = null;
-			int[] genericArgumentsResolvedPositions = null;
-			TypeBinding[] genericArgumentsTypeBindings = null;
-
-			if (method.binding != null) {
-				TypeBinding[] parameters = method.binding.parameters;
-				Argument[] arguments = method.arguments;
-				if ((parameters != null) && (arguments != null)) {
-					for (int i = 0, max = parameters.length; i < max; i++) {
-						TypeBinding argumentBinding = parameters[i];
-						if (localContentsOffset + 10 >= this.contents.length) {
-							resizeContents(10);
-						}
-						// now we can safely add the local entry
-						numberOfEntries++;
-						this.contents[localContentsOffset++] = 0;
-						this.contents[localContentsOffset++] = 0;
-						this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-						this.contents[localContentsOffset++] = (byte) code_length;
-						nameIndex = this.constantPool.literalIndex(arguments[i].name);
-						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-						this.contents[localContentsOffset++] = (byte) nameIndex;
-						int resolvedPosition = argSize;
-						if (argumentBinding.isParameterizedType() || argumentBinding.isTypeVariable()) {
-							if (genericArgumentsCounter == 0) {
-								// we cannot have more than max locals
-								genericArgumentsNameIndexes = new int[max];
-								genericArgumentsResolvedPositions = new int[max];
-								genericArgumentsTypeBindings = new TypeBinding[max];
-							}
-							genericArgumentsNameIndexes[genericArgumentsCounter] = nameIndex;
-							genericArgumentsResolvedPositions[genericArgumentsCounter] = resolvedPosition;
-							genericArgumentsTypeBindings[genericArgumentsCounter++] = argumentBinding;
-						}
-						descriptorIndex = this.constantPool.literalIndex(argumentBinding.signature());
-						this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-						this.contents[localContentsOffset++] = (byte) descriptorIndex;
-						switch(argumentBinding.id) {
-							case TypeIds.T_long :
-							case TypeIds.T_double :
-								argSize += 2;
-								break;
-							default :
-								argSize++;
-								break;
-						}
-						this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-						this.contents[localContentsOffset++] = (byte) resolvedPosition;
-					}
-				}
-			}
-			int value = numberOfEntries * 10 + 2;
-			this.contents[localVariableTableOffset++] = (byte) (value >> 24);
-			this.contents[localVariableTableOffset++] = (byte) (value >> 16);
-			this.contents[localVariableTableOffset++] = (byte) (value >> 8);
-			this.contents[localVariableTableOffset++] = (byte) value;
-			this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
-			this.contents[localVariableTableOffset] = (byte) numberOfEntries;
-			attributeNumber++;
-
-			final boolean currentInstanceIsGeneric =
-				!methodDeclarationIsStatic
-				&& declaringClassBinding != null
-				&& declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
-			if (genericLocalVariablesCounter != 0 || genericArgumentsCounter != 0 || currentInstanceIsGeneric) {
-				// add the local variable type table attribute
-				numberOfEntries = numberOfGenericEntries + genericArgumentsCounter + (currentInstanceIsGeneric ? 1 : 0);
-				// reserve enough space
-				int maxOfEntries = 8 + numberOfEntries * 10;
-				if (localContentsOffset + maxOfEntries >= this.contents.length) {
-					resizeContents(maxOfEntries);
-				}
-				int localVariableTypeNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
-				this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
-				value = numberOfEntries * 10 + 2;
-				this.contents[localContentsOffset++] = (byte) (value >> 24);
-				this.contents[localContentsOffset++] = (byte) (value >> 16);
-				this.contents[localContentsOffset++] = (byte) (value >> 8);
-				this.contents[localContentsOffset++] = (byte) value;
-				this.contents[localContentsOffset++] = (byte) (numberOfEntries >> 8);
-				this.contents[localContentsOffset++] = (byte) numberOfEntries;
-				if (currentInstanceIsGeneric) {
-					numberOfEntries++;
-					this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
-					this.contents[localContentsOffset++] = 0;
-					this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-					this.contents[localContentsOffset++] = (byte) code_length;
-					nameIndex = this.constantPool.literalIndex(ConstantPool.This);
-					this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) nameIndex;
-					descriptorIndex = this.constantPool.literalIndex(declaringClassBinding.genericTypeSignature());
-					this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) descriptorIndex;
-					this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
-					this.contents[localContentsOffset++] = 0;
-				}
-
-				for (int i = 0; i < genericLocalVariablesCounter; i++) {
-					LocalVariableBinding localVariable = genericLocalVariables[i];
-					this.contents[localContentsOffset++] = 0;
-					this.contents[localContentsOffset++] = 0;
-					this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-					this.contents[localContentsOffset++] = (byte) code_length;
-					nameIndex = this.constantPool.literalIndex(localVariable.name);
-					this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) nameIndex;
-					descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
-					this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) descriptorIndex;
-					int resolvedPosition = localVariable.resolvedPosition;
-					this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-					this.contents[localContentsOffset++] = (byte) resolvedPosition;
-				}
-				for (int i = 0; i < genericArgumentsCounter; i++) {
-					this.contents[localContentsOffset++] = 0;
-					this.contents[localContentsOffset++] = 0;
-					this.contents[localContentsOffset++] = (byte) (code_length >> 8);
-					this.contents[localContentsOffset++] = (byte) code_length;
-					nameIndex = genericArgumentsNameIndexes[i];
-					this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) nameIndex;
-					descriptorIndex = this.constantPool.literalIndex(genericArgumentsTypeBindings[i].genericTypeSignature());
-					this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) descriptorIndex;
-					int resolvedPosition = genericArgumentsResolvedPositions[i];
-					this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-					this.contents[localContentsOffset++] = (byte) resolvedPosition;
-				}
-				attributeNumber++;
-			}
+			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, false);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP_TABLE) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapTableAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
-					this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
-					int stackMapTableAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					numberOfFrames = 0;
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					StackMapFrame prevFrame = null;
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						prevFrame = currentFrame;
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						numberOfFrames++;
-						int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
-						switch (currentFrame.getFrameType(prevFrame)) {
-							case StackMapFrame.APPEND_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
-								int numberOfLocals = currentFrame.getNumberOfLocals();
-								for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
-									if (localContentsOffset + 6 >= this.contents.length) {
-										resizeContents(6);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfDifferentLocals--;
-									}
-								}
-								break;
-							case StackMapFrame.SAME_FRAME :
-								if (localContentsOffset + 1 >= this.contents.length) {
-									resizeContents(1);
-								}
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_FRAME_EXTENDED :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								this.contents[localContentsOffset++] = (byte) 251;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.CHOP_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
-								if (localContentsOffset + 6 >= this.contents.length) {
-									resizeContents(6);
-								}
-								this.contents[localContentsOffset++] = (byte) 247;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							default :
-								// FULL_FRAME
-								if (localContentsOffset + 5 >= this.contents.length) {
-									resizeContents(5);
-								}
-								this.contents[localContentsOffset++] = (byte) 255;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int numberOfLocalOffset = localContentsOffset;
-								localContentsOffset += 2; // leave two spots for number of locals
-								int numberOfLocalEntries = 0;
-								numberOfLocals = currentFrame.getNumberOfLocals();
-								int numberOfEntries = 0;
-								int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-								for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfLocalEntries++;
-									}
-									numberOfEntries++;
-								}
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-								this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-								int numberOfStackItems = currentFrame.numberOfStackItems;
-								this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-								this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-								for (int i = 0; i < numberOfStackItems; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.stackItems[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-									}
-								}
-						}
-					}
-
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapTableAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
-					this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
-					int stackMapAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int frameOffset = currentFrame.pc;
-						// FULL_FRAME
-						if (localContentsOffset + 5 >= this.contents.length) {
-							resizeContents(5);
-						}
-						this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
-						this.contents[localContentsOffset++] = (byte) frameOffset;
-						int numberOfLocalOffset = localContentsOffset;
-						localContentsOffset += 2; // leave two spots for number of locals
-						int numberOfLocalEntries = 0;
-						int numberOfLocals = currentFrame.getNumberOfLocals();
-						int numberOfEntries = 0;
-						int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-						for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.locals[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										i++;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										i++;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-								numberOfLocalEntries++;
-							}
-							numberOfEntries++;
-						}
-						if (localContentsOffset + 4 >= this.contents.length) {
-							resizeContents(4);
-						}
-						this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-						this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-						int numberOfStackItems = currentFrame.numberOfStackItems;
-						this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-						this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-						for (int i = 0; i < numberOfStackItems; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.stackItems[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-							}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
 		// update the number of attributes// ensure first that there is enough space available inside the localContents array
 		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
-		this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
 		// update the attribute length
-		int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
+		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
 		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
 		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
 		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
 		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-		this.contentsOffset = localContentsOffset;
 	}
 
 	/**
@@ -5149,10 +1721,10 @@
 	 * @param codeAttributeOffset <CODE>int</CODE>
 	 */
 	public void completeCodeAttributeForSyntheticMethod(
-		boolean hasExceptionHandlers,
-		SyntheticMethodBinding binding,
-		int codeAttributeOffset,
-		int[] startLineIndexes) {
+			boolean hasExceptionHandlers,
+			SyntheticMethodBinding binding,
+			int codeAttributeOffset,
+			int[] startLineIndexes) {
 		// reinitialize the contents with the byte modified by the code stream
 		this.contents = this.codeStream.bCodeStream;
 		int localContentsOffset = this.codeStream.classFileOffset;
@@ -5211,7 +1783,6 @@
 						if (addStackMaps) {
 							StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
 							stackMapFrameCodeStream.addFramePosition(handlerPC);
-//							stackMapFrameCodeStream.addExceptionMarker(handlerPC, exceptionLabel.exceptionType);
 						}
 						this.contents[localContentsOffset++] = (byte) (handlerPC >> 8);
 						this.contents[localContentsOffset++] = (byte) handlerPC;
@@ -5247,679 +1818,35 @@
 		}
 		// debug attributes
 		int codeAttributeAttributeOffset = localContentsOffset;
-		int attributeNumber = 0;
+		int attributesNumber = 0;
 		// leave two bytes for the attribute_length
 		localContentsOffset += 2;
 		if (localContentsOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
 
+		this.contentsOffset = localContentsOffset;
 		// first we handle the linenumber attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_LINES) != 0) {
-			if (localContentsOffset + 12 >= this.contents.length) {
-				resizeContents(12);
-			}
-			int index = 0;
-			int lineNumberNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
-			this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
-			int lineNumberTableOffset = localContentsOffset;
-			localContentsOffset += 6;
-			// leave space for attribute_length and line_number_table_length
-			// Seems like do would be better, but this preserves the existing behavior.
-			index = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1);
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = 0;
-			this.contents[localContentsOffset++] = (byte) (index >> 8);
-			this.contents[localContentsOffset++] = (byte) index;
-			// now we change the size of the line number attribute
-			this.contents[lineNumberTableOffset++] = 0;
-			this.contents[lineNumberTableOffset++] = 0;
-			this.contents[lineNumberTableOffset++] = 0;
-			this.contents[lineNumberTableOffset++] = 6;
-			this.contents[lineNumberTableOffset++] = 0;
-			this.contents[lineNumberTableOffset++] = 1;
-			attributeNumber++;
+			int lineNumber = Util.getLineNumber(binding.sourceStart, startLineIndexes, 0, startLineIndexes.length-1);
+			attributesNumber += generateLineNumberAttribute(lineNumber);
 		}
 		// then we do the local variable attribute
 		if ((this.produceAttributes & ClassFileConstants.ATTR_VARS) != 0) {
-			int numberOfEntries = 0;
-			int localVariableNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
-			if (localContentsOffset + 8 > this.contents.length) {
-				resizeContents(8);
-			}
-			this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
-			this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
-			int localVariableTableOffset = localContentsOffset;
-			localContentsOffset += 6;
-			// leave space for attribute_length and local_variable_table_length
-			int nameIndex;
-			int descriptorIndex;
-
-			// used to remember the local variable with a generic type
-			int genericLocalVariablesCounter = 0;
-			LocalVariableBinding[] genericLocalVariables = null;
-			int numberOfGenericEntries = 0;
-
-			for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
-				LocalVariableBinding localVariable = this.codeStream.locals[i];
-				if (localVariable.declaration == null) continue;
-				final TypeBinding localVariableTypeBinding = localVariable.type;
-				boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable();
-				if (localVariable.initializationCount != 0 && isParameterizedType) {
-					if (genericLocalVariables == null) {
-						// we cannot have more than max locals
-						genericLocalVariables = new LocalVariableBinding[max];
-					}
-					genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
-				}
-				for (int j = 0; j < localVariable.initializationCount; j++) {
-					int startPC = localVariable.initializationPCs[j << 1];
-					int endPC = localVariable.initializationPCs[(j << 1) + 1];
-					if (startPC != endPC) { // only entries for non zero length
-						if (endPC == -1) {
-							localVariable.declaringScope.problemReporter().abortDueToInternalError(
-								Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)),
-								(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
-						}
-						if (localContentsOffset + 10 > this.contents.length) {
-							resizeContents(10);
-						}
-						// now we can safely add the local entry
-						numberOfEntries++;
-						if (isParameterizedType) {
-							numberOfGenericEntries++;
-						}
-						this.contents[localContentsOffset++] = (byte) (startPC >> 8);
-						this.contents[localContentsOffset++] = (byte) startPC;
-						int length = endPC - startPC;
-						this.contents[localContentsOffset++] = (byte) (length >> 8);
-						this.contents[localContentsOffset++] = (byte) length;
-						nameIndex = this.constantPool.literalIndex(localVariable.name);
-						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-						this.contents[localContentsOffset++] = (byte) nameIndex;
-						descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
-						this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-						this.contents[localContentsOffset++] = (byte) descriptorIndex;
-						int resolvedPosition = localVariable.resolvedPosition;
-						this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-						this.contents[localContentsOffset++] = (byte) resolvedPosition;
-					}
-				}
-			}
-			int value = numberOfEntries * 10 + 2;
-			this.contents[localVariableTableOffset++] = (byte) (value >> 24);
-			this.contents[localVariableTableOffset++] = (byte) (value >> 16);
-			this.contents[localVariableTableOffset++] = (byte) (value >> 8);
-			this.contents[localVariableTableOffset++] = (byte) value;
-			this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
-			this.contents[localVariableTableOffset] = (byte) numberOfEntries;
-			attributeNumber++;
-
-			if (genericLocalVariablesCounter != 0) {
-				// add the local variable type table attribute
-				int maxOfEntries = 8 + numberOfGenericEntries * 10;
-				// reserve enough space
-				if (localContentsOffset + maxOfEntries >= this.contents.length) {
-					resizeContents(maxOfEntries);
-				}
-				int localVariableTypeNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
-				this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
-				this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
-				value = numberOfGenericEntries * 10 + 2;
-				this.contents[localContentsOffset++] = (byte) (value >> 24);
-				this.contents[localContentsOffset++] = (byte) (value >> 16);
-				this.contents[localContentsOffset++] = (byte) (value >> 8);
-				this.contents[localContentsOffset++] = (byte) value;
-				this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
-				this.contents[localContentsOffset++] = (byte) numberOfGenericEntries;
-
-				for (int i = 0; i < genericLocalVariablesCounter; i++) {
-					LocalVariableBinding localVariable = genericLocalVariables[i];
-					for (int j = 0; j < localVariable.initializationCount; j++) {
-						int startPC = localVariable.initializationPCs[j << 1];
-						int endPC = localVariable.initializationPCs[(j << 1) + 1];
-						if (startPC != endPC) { // only entries for non zero length
-							// now we can safely add the local entry
-							this.contents[localContentsOffset++] = (byte) (startPC >> 8);
-							this.contents[localContentsOffset++] = (byte) startPC;
-							int length = endPC - startPC;
-							this.contents[localContentsOffset++] = (byte) (length >> 8);
-							this.contents[localContentsOffset++] = (byte) length;
-							nameIndex = this.constantPool.literalIndex(localVariable.name);
-							this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) nameIndex;
-							descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
-							this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
-							this.contents[localContentsOffset++] = (byte) descriptorIndex;
-							int resolvedPosition = localVariable.resolvedPosition;
-							this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
-							this.contents[localContentsOffset++] = (byte) resolvedPosition;
-						}
-					}
-				}
-				attributeNumber++;
-			}
+			final boolean methodDeclarationIsStatic = binding.isStatic();
+			attributesNumber += generateLocalVariableTableAttribute(code_length, methodDeclarationIsStatic, true);
 		}
-
 		if (addStackMaps) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapTableAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
-					this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
-
-					int stackMapTableAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					StackMapFrame prevFrame = null;
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						prevFrame = currentFrame;
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
-						switch (currentFrame.getFrameType(prevFrame)) {
-							case StackMapFrame.APPEND_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
-								int numberOfLocals = currentFrame.getNumberOfLocals();
-								for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
-									if (localContentsOffset + 6 >= this.contents.length) {
-										resizeContents(6);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfDifferentLocals--;
-									}
-								}
-								break;
-							case StackMapFrame.SAME_FRAME :
-								if (localContentsOffset + 1 >= this.contents.length) {
-									resizeContents(1);
-								}
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_FRAME_EXTENDED :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								this.contents[localContentsOffset++] = (byte) 251;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.CHOP_FRAME :
-								if (localContentsOffset + 3 >= this.contents.length) {
-									resizeContents(3);
-								}
-								numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
-								this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
-								if (localContentsOffset + 6 >= this.contents.length) {
-									resizeContents(6);
-								}
-								this.contents[localContentsOffset++] = (byte) 247;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								if (currentFrame.stackItems[0] == null) {
-									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-								} else {
-									switch(currentFrame.stackItems[0].id()) {
-										case T_boolean :
-										case T_byte :
-										case T_char :
-										case T_int :
-										case T_short :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-											break;
-										case T_float :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-											break;
-										case T_long :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-											break;
-										case T_double :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-											break;
-										case T_null :
-											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-											break;
-										default:
-											VerificationTypeInfo info = currentFrame.stackItems[0];
-											byte tag = (byte) info.tag;
-											this.contents[localContentsOffset++] = tag;
-											switch (tag) {
-												case VerificationTypeInfo.ITEM_UNINITIALIZED :
-													int offset = info.offset;
-													this.contents[localContentsOffset++] = (byte) (offset >> 8);
-													this.contents[localContentsOffset++] = (byte) offset;
-													break;
-												case VerificationTypeInfo.ITEM_OBJECT :
-													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-													this.contents[localContentsOffset++] = (byte) indexForType;
-											}
-									}
-								}
-								break;
-							default :
-								// FULL_FRAME
-								if (localContentsOffset + 5 >= this.contents.length) {
-									resizeContents(5);
-								}
-								this.contents[localContentsOffset++] = (byte) 255;
-								this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
-								this.contents[localContentsOffset++] = (byte) offsetDelta;
-								int numberOfLocalOffset = localContentsOffset;
-								localContentsOffset += 2; // leave two spots for number of locals
-								int numberOfLocalEntries = 0;
-								numberOfLocals = currentFrame.getNumberOfLocals();
-								int numberOfEntries = 0;
-								int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-								for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.locals[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												i++;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												i++;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-										numberOfLocalEntries++;
-									}
-									numberOfEntries++;
-								}
-								if (localContentsOffset + 4 >= this.contents.length) {
-									resizeContents(4);
-								}
-								this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-								this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-								int numberOfStackItems = currentFrame.numberOfStackItems;
-								this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-								this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-								for (int i = 0; i < numberOfStackItems; i++) {
-									if (localContentsOffset + 3 >= this.contents.length) {
-										resizeContents(3);
-									}
-									VerificationTypeInfo info = currentFrame.stackItems[i];
-									if (info == null) {
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-									} else {
-										switch(info.id()) {
-											case T_boolean :
-											case T_byte :
-											case T_char :
-											case T_int :
-											case T_short :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-												break;
-											case T_float :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-												break;
-											case T_long :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-												break;
-											case T_double :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-												break;
-											case T_null :
-												this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-												break;
-											default:
-												this.contents[localContentsOffset++] = (byte) info.tag;
-												switch (info.tag) {
-													case VerificationTypeInfo.ITEM_UNINITIALIZED :
-														int offset = info.offset;
-														this.contents[localContentsOffset++] = (byte) (offset >> 8);
-														this.contents[localContentsOffset++] = (byte) offset;
-														break;
-													case VerificationTypeInfo.ITEM_OBJECT :
-														int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-														this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-														this.contents[localContentsOffset++] = (byte) indexForType;
-												}
-										}
-									}
-								}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapTableAttribute(binding, code_length, codeAttributeOffset, max_locals, false);
 		}
 
 		if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) {
-			StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
-			stackMapFrameCodeStream.removeFramePosition(code_length);
-			if (stackMapFrameCodeStream.hasFramePositions()) {
-				ArrayList frames = new ArrayList();
-				traverse(this.codeStream.methodDeclaration.binding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, false);
-				int numberOfFrames = frames.size();
-				if (numberOfFrames > 1) {
-					int stackMapTableAttributeOffset = localContentsOffset;
-					// add the stack map table attribute
-					if (localContentsOffset + 8 >= this.contents.length) {
-						resizeContents(8);
-					}
-					int stackMapAttributeNameIndex =
-						this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
-					this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
-					this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
-
-					int stackMapAttributeLengthOffset = localContentsOffset;
-					// generate the attribute
-					localContentsOffset += 4;
-					if (localContentsOffset + 4 >= this.contents.length) {
-						resizeContents(4);
-					}
-					int numberOfFramesOffset = localContentsOffset;
-					localContentsOffset += 2;
-					if (localContentsOffset + 2 >= this.contents.length) {
-						resizeContents(2);
-					}
-					StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
-					for (int j = 1; j < numberOfFrames; j++) {
-						// select next frame
-						currentFrame = (StackMapFrame) frames.get(j);
-						// generate current frame
-						// need to find differences between the current frame and the previous frame
-						int frameOffset = currentFrame.pc;
-						// FULL_FRAME
-						if (localContentsOffset + 5 >= this.contents.length) {
-							resizeContents(5);
-						}
-						this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
-						this.contents[localContentsOffset++] = (byte) frameOffset;
-						int numberOfLocalOffset = localContentsOffset;
-						localContentsOffset += 2; // leave two spots for number of locals
-						int numberOfLocalEntries = 0;
-						int numberOfLocals = currentFrame.getNumberOfLocals();
-						int numberOfEntries = 0;
-						int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
-						for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.locals[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										i++;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										i++;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-								numberOfLocalEntries++;
-							}
-							numberOfEntries++;
-						}
-						if (localContentsOffset + 4 >= this.contents.length) {
-							resizeContents(4);
-						}
-						this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
-						this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
-						int numberOfStackItems = currentFrame.numberOfStackItems;
-						this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
-						this.contents[localContentsOffset++] = (byte) numberOfStackItems;
-						for (int i = 0; i < numberOfStackItems; i++) {
-							if (localContentsOffset + 3 >= this.contents.length) {
-								resizeContents(3);
-							}
-							VerificationTypeInfo info = currentFrame.stackItems[i];
-							if (info == null) {
-								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
-							} else {
-								switch(info.id()) {
-									case T_boolean :
-									case T_byte :
-									case T_char :
-									case T_int :
-									case T_short :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
-										break;
-									case T_float :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
-										break;
-									case T_long :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
-										break;
-									case T_double :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
-										break;
-									case T_null :
-										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
-										break;
-									default:
-										this.contents[localContentsOffset++] = (byte) info.tag;
-									switch (info.tag) {
-										case VerificationTypeInfo.ITEM_UNINITIALIZED :
-											int offset = info.offset;
-											this.contents[localContentsOffset++] = (byte) (offset >> 8);
-											this.contents[localContentsOffset++] = (byte) offset;
-											break;
-										case VerificationTypeInfo.ITEM_OBJECT :
-											int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
-											this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
-											this.contents[localContentsOffset++] = (byte) indexForType;
-									}
-								}
-							}
-						}
-					}
-
-					numberOfFrames--;
-					if (numberOfFrames != 0) {
-						this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
-						this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
-
-						int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
-						this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
-						this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
-						attributeNumber++;
-					} else {
-						localContentsOffset = stackMapTableAttributeOffset;
-					}
-				}
-			}
+			attributesNumber += generateStackMapAttribute(
+					binding,
+					code_length,
+					codeAttributeOffset,
+					max_locals,
+					false);
 		}
 
 		// update the number of attributes
@@ -5927,16 +1854,14 @@
 		if (codeAttributeAttributeOffset + 2 >= this.contents.length) {
 			resizeContents(2);
 		}
-		this.contents[codeAttributeAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[codeAttributeAttributeOffset] = (byte) attributeNumber;
-
+		this.contents[codeAttributeAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[codeAttributeAttributeOffset] = (byte) attributesNumber;
 		// update the attribute length
-		int codeAttributeLength = localContentsOffset - (codeAttributeOffset + 6);
+		int codeAttributeLength = this.contentsOffset - (codeAttributeOffset + 6);
 		this.contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
 		this.contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
 		this.contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
 		this.contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-		this.contentsOffset = localContentsOffset;
 	}
 
 	/**
@@ -5953,9 +1878,9 @@
 	 * @param codeAttributeOffset <CODE>int</CODE>
 	 */
 	public void completeCodeAttributeForSyntheticMethod(
-		SyntheticMethodBinding binding,
-		int codeAttributeOffset,
-		int[] startLineIndexes) {
+			SyntheticMethodBinding binding,
+			int codeAttributeOffset,
+			int[] startLineIndexes) {
 
 		this.completeCodeAttributeForSyntheticMethod(
 				false,
@@ -5969,16 +1894,16 @@
 	 * Complete the creation of a method info by setting up the number of attributes at the right offset.
 	 *
 	 * @param methodAttributeOffset <CODE>int</CODE>
-	 * @param attributeNumber <CODE>int</CODE>
+	 * @param attributesNumber <CODE>int</CODE>
 	 */
 	public void completeMethodInfo(
-		int methodAttributeOffset,
-		int attributeNumber) {
+			MethodBinding binding,
+			int methodAttributeOffset,
+			int attributesNumber) {
 		// update the number of attributes
-		this.contents[methodAttributeOffset++] = (byte) (attributeNumber >> 8);
-		this.contents[methodAttributeOffset] = (byte) attributeNumber;
+		this.contents[methodAttributeOffset++] = (byte) (attributesNumber >> 8);
+		this.contents[methodAttributeOffset] = (byte) attributesNumber;
 	}
-
 	/**
 	 * INTERNAL USE-ONLY
 	 * This methods returns a char[] representing the file name of the receiver
@@ -6064,6 +1989,29 @@
 		}
 	}
 
+	private int generateAnnotationDefaultAttribute(AnnotationMethodDeclaration declaration, int attributeOffset) {
+		int attributesNumber = 0;
+		// add an annotation default attribute
+		int annotationDefaultNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.AnnotationDefaultName);
+		if (this.contentsOffset + 6 >= this.contents.length) {
+			resizeContents(6);
+		}
+		this.contents[this.contentsOffset++] = (byte) (annotationDefaultNameIndex >> 8);
+		this.contents[this.contentsOffset++] = (byte) annotationDefaultNameIndex;
+		int attributeLengthOffset = this.contentsOffset;
+		this.contentsOffset += 4;
+		generateElementValue(declaration.defaultValue, declaration.binding.returnType, attributeOffset);
+		if (this.contentsOffset != attributeOffset) {
+			int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
+			this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
+			this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
+			this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
+			this.contents[attributeLengthOffset++] = (byte) attributeLength;
+			attributesNumber++;
+		}
+		return attributesNumber;
+	}
 	/**
 	 * INTERNAL USE-ONLY
 	 * That method generates the header of a code attribute.
@@ -6081,7 +2029,104 @@
 		// leave space for attribute_length(4), max_stack(2), max_locals(2), code_length(4)
 		this.contentsOffset += 12;
 	}
-
+	
+	private int generateConstantValueAttribute(Constant fieldConstant, FieldBinding fieldBinding, int fieldAttributeOffset) {
+		int localContentsOffset = this.contentsOffset;
+		int attributesNumber = 1;
+		if (localContentsOffset + 8 >= this.contents.length) {
+			resizeContents(8);
+		}
+		// Now we generate the constant attribute corresponding to the fieldBinding
+		int constantValueNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.ConstantValueName);
+		this.contents[localContentsOffset++] = (byte) (constantValueNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) constantValueNameIndex;
+		// The attribute length = 2 in case of a constantValue attribute
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 2;
+		// Need to add the constant_value_index
+		switch (fieldConstant.typeID()) {
+			case T_boolean :
+				int booleanValueIndex =
+					this.constantPool.literalIndex(fieldConstant.booleanValue() ? 1 : 0);
+				this.contents[localContentsOffset++] = (byte) (booleanValueIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) booleanValueIndex;
+				break;
+			case T_byte :
+			case T_char :
+			case T_int :
+			case T_short :
+				int integerValueIndex =
+					this.constantPool.literalIndex(fieldConstant.intValue());
+				this.contents[localContentsOffset++] = (byte) (integerValueIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) integerValueIndex;
+				break;
+			case T_float :
+				int floatValueIndex =
+					this.constantPool.literalIndex(fieldConstant.floatValue());
+				this.contents[localContentsOffset++] = (byte) (floatValueIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) floatValueIndex;
+				break;
+			case T_double :
+				int doubleValueIndex =
+					this.constantPool.literalIndex(fieldConstant.doubleValue());
+				this.contents[localContentsOffset++] = (byte) (doubleValueIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) doubleValueIndex;
+				break;
+			case T_long :
+				int longValueIndex =
+					this.constantPool.literalIndex(fieldConstant.longValue());
+				this.contents[localContentsOffset++] = (byte) (longValueIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) longValueIndex;
+				break;
+			case T_JavaLangString :
+				int stringValueIndex =
+					this.constantPool.literalIndex(
+						((StringConstant) fieldConstant).stringValue());
+				if (stringValueIndex == -1) {
+					if (!this.creatingProblemType) {
+						// report an error and abort: will lead to a problem type classfile creation
+						TypeDeclaration typeDeclaration = this.referenceBinding.scope.referenceContext;
+						FieldDeclaration[] fieldDecls = typeDeclaration.fields;
+						for (int i = 0, max = fieldDecls.length; i < max; i++) {
+							if (fieldDecls[i].binding == fieldBinding) {
+								// problem should abort
+								typeDeclaration.scope.problemReporter().stringConstantIsExceedingUtf8Limit(
+									fieldDecls[i]);
+							}
+						}
+					} else {
+						// already inside a problem type creation : no constant for this field
+						this.contentsOffset = fieldAttributeOffset;
+						attributesNumber = 0;
+					}
+				} else {
+					this.contents[localContentsOffset++] = (byte) (stringValueIndex >> 8);
+					this.contents[localContentsOffset++] = (byte) stringValueIndex;
+				}
+		}
+		this.contentsOffset = localContentsOffset;
+		return attributesNumber;
+	}
+	private int generateDeprecatedAttribute() {
+		int localContentsOffset = this.contentsOffset;
+		if (localContentsOffset + 6 >= this.contents.length) {
+			resizeContents(6);
+		}
+		int deprecatedAttributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
+		this.contents[localContentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) deprecatedAttributeNameIndex;
+		// the length of a deprecated attribute is equals to 0
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
 	private void generateElementValue(
 			Expression defaultValue,
 			TypeBinding memberValuePairReturnType,
@@ -6107,7 +2152,6 @@
 			}
 		}
 	}
-
 	/**
 	 * @param attributeOffset
 	 */
@@ -6191,7 +2235,7 @@
 				}
 		}
 	}
-
+	
 	private void generateElementValueForNonConstantExpression(Expression defaultValue, int attributeOffset, TypeBinding defaultValueBinding) {
 		if (defaultValueBinding != null) {
 			if (defaultValueBinding.isEnum()) {
@@ -6260,6 +2304,413 @@
 		}
 	}
 
+	private int generateEnclosingMethodAttribute() {
+		int localContentsOffset = this.contentsOffset;
+		// add enclosing method attribute (1.5 mode only)
+		if (localContentsOffset + 10 >= this.contents.length) {
+			resizeContents(10);
+		}
+		int enclosingMethodAttributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.EnclosingMethodName);
+		this.contents[localContentsOffset++] = (byte) (enclosingMethodAttributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) enclosingMethodAttributeNameIndex;
+		// the length of a signature attribute is equals to 2
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 4;
+
+		int enclosingTypeIndex = this.constantPool.literalIndexForType(this.referenceBinding.enclosingType().constantPoolName());
+		this.contents[localContentsOffset++] = (byte) (enclosingTypeIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) enclosingTypeIndex;
+		byte methodIndexByte1 = 0;
+		byte methodIndexByte2 = 0;
+		if (this.referenceBinding instanceof LocalTypeBinding) {
+			MethodBinding methodBinding = ((LocalTypeBinding) this.referenceBinding).enclosingMethod;
+			if (methodBinding != null) {
+//{ObjectTeams: static role methods need to know the constant pool declaring class:
+/* orig:
+				int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this));
+  :giro */
+				int enclosingMethodIndex = this.constantPool.literalIndexForNameAndType(methodBinding.selector, methodBinding.signature(this, this.referenceBinding));
+// SH}
+				methodIndexByte1 = (byte) (enclosingMethodIndex >> 8);
+				methodIndexByte2 = (byte) enclosingMethodIndex;
+			}
+		}
+		this.contents[localContentsOffset++] = methodIndexByte1;
+		this.contents[localContentsOffset++] = methodIndexByte2;
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+	private int generateExceptionsAttribute(ReferenceBinding[] thrownsExceptions) {
+		int localContentsOffset = this.contentsOffset;
+		int length = thrownsExceptions.length;
+		int exSize = 8 + length * 2;
+		if (exSize + this.contentsOffset >= this.contents.length) {
+			resizeContents(exSize);
+		}
+		int exceptionNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.ExceptionsName);
+		this.contents[localContentsOffset++] = (byte) (exceptionNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) exceptionNameIndex;
+		// The attribute length = length * 2 + 2 in case of a exception attribute
+		int attributeLength = length * 2 + 2;
+		this.contents[localContentsOffset++] = (byte) (attributeLength >> 24);
+		this.contents[localContentsOffset++] = (byte) (attributeLength >> 16);
+		this.contents[localContentsOffset++] = (byte) (attributeLength >> 8);
+		this.contents[localContentsOffset++] = (byte) attributeLength;
+		this.contents[localContentsOffset++] = (byte) (length >> 8);
+		this.contents[localContentsOffset++] = (byte) length;
+		for (int i = 0; i < length; i++) {
+			int exceptionIndex = this.constantPool.literalIndexForType(thrownsExceptions[i]);
+			this.contents[localContentsOffset++] = (byte) (exceptionIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) exceptionIndex;
+		}
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+	private int generateHierarchyInconsistentAttribute() {
+		int localContentsOffset = this.contentsOffset;
+		// add an attribute for inconsistent hierarchy
+		if (localContentsOffset + 6 >= this.contents.length) {
+			resizeContents(6);
+		}
+		int inconsistentHierarchyNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.InconsistentHierarchy);
+		this.contents[localContentsOffset++] = (byte) (inconsistentHierarchyNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) inconsistentHierarchyNameIndex;
+		// the length of an inconsistent hierarchy attribute is equals to 0
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+	private int generateInnerClassAttribute(int numberOfInnerClasses, ReferenceBinding[] innerClasses) {
+		int localContentsOffset = this.contentsOffset;
+		// Generate the inner class attribute
+		int exSize = 8 * numberOfInnerClasses + 8;
+		if (exSize + localContentsOffset >= this.contents.length) {
+			resizeContents(exSize);
+		}
+		// Now we now the size of the attribute and the number of entries
+		// attribute name
+		int attributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.InnerClassName);
+		this.contents[localContentsOffset++] = (byte) (attributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) attributeNameIndex;
+		int value = (numberOfInnerClasses << 3) + 2;
+		this.contents[localContentsOffset++] = (byte) (value >> 24);
+		this.contents[localContentsOffset++] = (byte) (value >> 16);
+		this.contents[localContentsOffset++] = (byte) (value >> 8);
+		this.contents[localContentsOffset++] = (byte) value;
+		this.contents[localContentsOffset++] = (byte) (numberOfInnerClasses >> 8);
+		this.contents[localContentsOffset++] = (byte) numberOfInnerClasses;
+		for (int i = 0; i < numberOfInnerClasses; i++) {
+			ReferenceBinding innerClass = innerClasses[i];
+			int accessFlags = innerClass.getAccessFlags();
+//{ObjectTeams: synthetic interfaces are illegal in class files (why???):
+			if (  (accessFlags & (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
+		              == (ClassFileConstants.AccSynthetic|ClassFileConstants.AccInterface))
+			{
+				accessFlags ^= ClassFileConstants.AccSynthetic;
+			}
+//SH}
+			int innerClassIndex = this.constantPool.literalIndexForType(innerClass.constantPoolName());
+			// inner class index
+			this.contents[localContentsOffset++] = (byte) (innerClassIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) innerClassIndex;
+			// outer class index: anonymous and local have no outer class index
+			if (innerClass.isMemberType()) {
+				// member or member of local
+				int outerClassIndex = this.constantPool.literalIndexForType(innerClass.enclosingType().constantPoolName());
+				this.contents[localContentsOffset++] = (byte) (outerClassIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) outerClassIndex;
+			} else {
+				// equals to 0 if the innerClass is not a member type
+				this.contents[localContentsOffset++] = 0;
+				this.contents[localContentsOffset++] = 0;
+			}
+			// name index
+			if (!innerClass.isAnonymousType()) {
+//{ObjectTeams: use real name not beautified version (was sourceName()).
+/* orig:
+				int nameIndex = this.constantPool.literalIndex(innerClass.sourceName());
+  :giro */
+				int nameIndex = this.constantPool.literalIndex(innerClass.internalName());
+// SH}
+
+				this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) nameIndex;
+			} else {
+				// equals to 0 if the innerClass is an anonymous type
+				this.contents[localContentsOffset++] = 0;
+				this.contents[localContentsOffset++] = 0;
+			}
+			// access flag
+			if (innerClass.isAnonymousType()) {
+				accessFlags &= ~ClassFileConstants.AccFinal;
+			} else if (innerClass.isMemberType() && innerClass.isInterface()) {
+				accessFlags |= ClassFileConstants.AccStatic; // implicitely static
+			}
+			this.contents[localContentsOffset++] = (byte) (accessFlags >> 8);
+			this.contents[localContentsOffset++] = (byte) accessFlags;
+		}
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+	private int generateLineNumberAttribute() {
+		int localContentsOffset = this.contentsOffset;
+		int attributesNumber = 0;
+		/* Create and add the line number attribute (used for debugging)
+		 * Build the pairs of:
+		 * 	(bytecodePC lineNumber)
+		 * according to the table of start line indexes and the pcToSourceMap table
+		 * contained into the codestream
+		 */
+		int[] pcToSourceMapTable;
+		if (((pcToSourceMapTable = this.codeStream.pcToSourceMap) != null)
+			&& (this.codeStream.pcToSourceMapSize != 0)) {
+			int lineNumberNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
+			if (localContentsOffset + 8 >= this.contents.length) {
+				resizeContents(8);
+			}
+			this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
+			int lineNumberTableOffset = localContentsOffset;
+			localContentsOffset += 6;
+			// leave space for attribute_length and line_number_table_length
+			int numberOfEntries = 0;
+			int length = this.codeStream.pcToSourceMapSize;
+			for (int i = 0; i < length;) {
+				// write the entry
+				if (localContentsOffset + 4 >= this.contents.length) {
+					resizeContents(4);
+				}
+				int pc = pcToSourceMapTable[i++];
+				this.contents[localContentsOffset++] = (byte) (pc >> 8);
+				this.contents[localContentsOffset++] = (byte) pc;
+				int lineNumber = pcToSourceMapTable[i++];
+				this.contents[localContentsOffset++] = (byte) (lineNumber >> 8);
+				this.contents[localContentsOffset++] = (byte) lineNumber;
+				numberOfEntries++;
+			}
+			// now we change the size of the line number attribute
+			int lineNumberAttr_length = numberOfEntries * 4 + 2;
+			this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 24);
+			this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 16);
+			this.contents[lineNumberTableOffset++] = (byte) (lineNumberAttr_length >> 8);
+			this.contents[lineNumberTableOffset++] = (byte) lineNumberAttr_length;
+			this.contents[lineNumberTableOffset++] = (byte) (numberOfEntries >> 8);
+			this.contents[lineNumberTableOffset++] = (byte) numberOfEntries;
+			attributesNumber = 1;
+		}
+		this.contentsOffset = localContentsOffset;
+		return attributesNumber;
+	}
+	// this is used for problem and synthetic methods
+	private int generateLineNumberAttribute(int problemLine) {
+		int localContentsOffset = this.contentsOffset;
+		if (localContentsOffset + 12 >= this.contents.length) {
+			resizeContents(12);
+		}
+		/* Create and add the line number attribute (used for debugging)
+		 * Build the pairs of:
+		 * (bytecodePC lineNumber)
+		 * according to the table of start line indexes and the pcToSourceMap table
+		 * contained into the codestream
+		 */
+		int lineNumberNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.LineNumberTableName);
+		this.contents[localContentsOffset++] = (byte) (lineNumberNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) lineNumberNameIndex;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 6;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 1;
+		// first entry at pc = 0
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = (byte) (problemLine >> 8);
+		this.contents[localContentsOffset++] = (byte) problemLine;
+		// now we change the size of the line number attribute
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+	
+	private int generateLocalVariableTableAttribute(int code_length, boolean methodDeclarationIsStatic, boolean isSynthetic) {
+		int attributesNumber = 0;
+		int localContentsOffset = this.contentsOffset;
+		int numberOfEntries = 0;
+		int localVariableNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTableName);
+		int maxOfEntries = 8 + 10 * (methodDeclarationIsStatic ? 0 : 1);
+		for (int i = 0; i < this.codeStream.allLocalsCounter; i++) {
+			LocalVariableBinding localVariableBinding = this.codeStream.locals[i];
+			maxOfEntries += 10 * localVariableBinding.initializationCount;
+		}
+		// reserve enough space
+		if (localContentsOffset + maxOfEntries >= this.contents.length) {
+			resizeContents(maxOfEntries);
+		}
+		this.contents[localContentsOffset++] = (byte) (localVariableNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) localVariableNameIndex;
+		int localVariableTableOffset = localContentsOffset;
+		// leave space for attribute_length and local_variable_table_length
+		localContentsOffset += 6;
+		int nameIndex;
+		int descriptorIndex;
+		SourceTypeBinding declaringClassBinding = null;
+		if (!methodDeclarationIsStatic && !isSynthetic) {
+			numberOfEntries++;
+			this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
+			this.contents[localContentsOffset++] = 0;
+			this.contents[localContentsOffset++] = (byte) (code_length >> 8);
+			this.contents[localContentsOffset++] = (byte) code_length;
+			nameIndex = this.constantPool.literalIndex(ConstantPool.This);
+			this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) nameIndex;
+			declaringClassBinding = (SourceTypeBinding) this.codeStream.methodDeclaration.binding.declaringClass;
+			descriptorIndex =
+				this.constantPool.literalIndex(
+					declaringClassBinding.signature());
+			this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) descriptorIndex;
+			this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
+			this.contents[localContentsOffset++] = 0;
+		}
+		// used to remember the local variable with a generic type
+		int genericLocalVariablesCounter = 0;
+		LocalVariableBinding[] genericLocalVariables = null;
+		int numberOfGenericEntries = 0;
+
+		for (int i = 0, max = this.codeStream.allLocalsCounter; i < max; i++) {
+			LocalVariableBinding localVariable = this.codeStream.locals[i];
+			int initializationCount = localVariable.initializationCount;
+			if (initializationCount == 0) continue;
+			if (localVariable.declaration == null) continue;
+			final TypeBinding localVariableTypeBinding = localVariable.type;
+			boolean isParameterizedType = localVariableTypeBinding.isParameterizedType() || localVariableTypeBinding.isTypeVariable();
+			if (isParameterizedType) {
+				if (genericLocalVariables == null) {
+					// we cannot have more than max locals
+					genericLocalVariables = new LocalVariableBinding[max];
+				}
+				genericLocalVariables[genericLocalVariablesCounter++] = localVariable;
+			}
+			for (int j = 0; j < initializationCount; j++) {
+				int startPC = localVariable.initializationPCs[j << 1];
+				int endPC = localVariable.initializationPCs[(j << 1) + 1];
+				if (startPC != endPC) { // only entries for non zero length
+					if (endPC == -1) {
+						localVariable.declaringScope.problemReporter().abortDueToInternalError(
+								Messages.bind(Messages.abort_invalidAttribute, new String(localVariable.name)),
+								(ASTNode) localVariable.declaringScope.methodScope().referenceContext);
+					}
+					if (isParameterizedType) {
+						numberOfGenericEntries++;
+					}
+					// now we can safely add the local entry
+					numberOfEntries++;
+					this.contents[localContentsOffset++] = (byte) (startPC >> 8);
+					this.contents[localContentsOffset++] = (byte) startPC;
+					int length = endPC - startPC;
+					this.contents[localContentsOffset++] = (byte) (length >> 8);
+					this.contents[localContentsOffset++] = (byte) length;
+					nameIndex = this.constantPool.literalIndex(localVariable.name);
+					this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+					this.contents[localContentsOffset++] = (byte) nameIndex;
+					descriptorIndex = this.constantPool.literalIndex(localVariableTypeBinding.signature());
+					this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
+					this.contents[localContentsOffset++] = (byte) descriptorIndex;
+					int resolvedPosition = localVariable.resolvedPosition;
+					this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
+					this.contents[localContentsOffset++] = (byte) resolvedPosition;
+				}
+			}
+		}
+		int value = numberOfEntries * 10 + 2;
+		this.contents[localVariableTableOffset++] = (byte) (value >> 24);
+		this.contents[localVariableTableOffset++] = (byte) (value >> 16);
+		this.contents[localVariableTableOffset++] = (byte) (value >> 8);
+		this.contents[localVariableTableOffset++] = (byte) value;
+		this.contents[localVariableTableOffset++] = (byte) (numberOfEntries >> 8);
+		this.contents[localVariableTableOffset] = (byte) numberOfEntries;
+		attributesNumber++;
+
+		final boolean currentInstanceIsGeneric =
+			!methodDeclarationIsStatic
+			&& declaringClassBinding != null
+			&& declaringClassBinding.typeVariables != Binding.NO_TYPE_VARIABLES;
+		if (genericLocalVariablesCounter != 0 || currentInstanceIsGeneric) {
+			// add the local variable type table attribute
+			numberOfGenericEntries += (currentInstanceIsGeneric ? 1 : 0);
+			maxOfEntries = 8 + numberOfGenericEntries * 10;
+			// reserve enough space
+			if (localContentsOffset + maxOfEntries >= this.contents.length) {
+				resizeContents(maxOfEntries);
+			}
+			int localVariableTypeNameIndex =
+				this.constantPool.literalIndex(AttributeNamesConstants.LocalVariableTypeTableName);
+			this.contents[localContentsOffset++] = (byte) (localVariableTypeNameIndex >> 8);
+			this.contents[localContentsOffset++] = (byte) localVariableTypeNameIndex;
+			value = numberOfGenericEntries * 10 + 2;
+			this.contents[localContentsOffset++] = (byte) (value >> 24);
+			this.contents[localContentsOffset++] = (byte) (value >> 16);
+			this.contents[localContentsOffset++] = (byte) (value >> 8);
+			this.contents[localContentsOffset++] = (byte) value;
+			this.contents[localContentsOffset++] = (byte) (numberOfGenericEntries >> 8);
+			this.contents[localContentsOffset++] = (byte) numberOfGenericEntries;
+			if (currentInstanceIsGeneric) {
+				this.contents[localContentsOffset++] = 0; // the startPC for this is always 0
+				this.contents[localContentsOffset++] = 0;
+				this.contents[localContentsOffset++] = (byte) (code_length >> 8);
+				this.contents[localContentsOffset++] = (byte) code_length;
+				nameIndex = this.constantPool.literalIndex(ConstantPool.This);
+				this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) nameIndex;
+				descriptorIndex = this.constantPool.literalIndex(declaringClassBinding.genericTypeSignature());
+				this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) descriptorIndex;
+				this.contents[localContentsOffset++] = 0;// the resolved position for this is always 0
+				this.contents[localContentsOffset++] = 0;
+			}
+
+			for (int i = 0; i < genericLocalVariablesCounter; i++) {
+				LocalVariableBinding localVariable = genericLocalVariables[i];
+				for (int j = 0; j < localVariable.initializationCount; j++) {
+					int startPC = localVariable.initializationPCs[j << 1];
+					int endPC = localVariable.initializationPCs[(j << 1) + 1];
+					if (startPC != endPC) {
+						// only entries for non zero length
+						// now we can safely add the local entry
+						this.contents[localContentsOffset++] = (byte) (startPC >> 8);
+						this.contents[localContentsOffset++] = (byte) startPC;
+						int length = endPC - startPC;
+						this.contents[localContentsOffset++] = (byte) (length >> 8);
+						this.contents[localContentsOffset++] = (byte) length;
+						nameIndex = this.constantPool.literalIndex(localVariable.name);
+						this.contents[localContentsOffset++] = (byte) (nameIndex >> 8);
+						this.contents[localContentsOffset++] = (byte) nameIndex;
+						descriptorIndex = this.constantPool.literalIndex(localVariable.type.genericTypeSignature());
+						this.contents[localContentsOffset++] = (byte) (descriptorIndex >> 8);
+						this.contents[localContentsOffset++] = (byte) descriptorIndex;
+						int resolvedPosition = localVariable.resolvedPosition;
+						this.contents[localContentsOffset++] = (byte) (resolvedPosition >> 8);
+						this.contents[localContentsOffset++] = (byte) resolvedPosition;
+					}
+				}
+			}
+			attributesNumber++;
+		}
+		this.contentsOffset = localContentsOffset;
+		return attributesNumber;
+	}
 	/**
 	 * INTERNAL USE-ONLY
 	 * That method generates the attributes of a code attribute.
@@ -6273,7 +2724,7 @@
 	 * @param methodBinding org.eclipse.jdt.internal.compiler.lookup.MethodBinding
 	 * @return <CODE>int</CODE>
 	 */
-	public int generateMethodInfoAttribute(MethodBinding methodBinding) {
+	public int generateMethodInfoAttributes(MethodBinding methodBinding) {
 		// leave two bytes for the attribute_number
 		this.contentsOffset += 2;
 		if (this.contentsOffset + 2 >= this.contents.length) {
@@ -6288,127 +2739,40 @@
 
 		// Exception attribute
 		ReferenceBinding[] thrownsExceptions;
-		int attributeNumber = 0;
+		int attributesNumber = 0;
 		if ((thrownsExceptions = methodBinding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
 			// The method has a throw clause. So we need to add an exception attribute
 			// check that there is enough space to write all the bytes for the exception attribute
-			int length = thrownsExceptions.length;
-			int exSize = 8 + length * 2;
-			if (exSize + this.contentsOffset >= this.contents.length) {
-				resizeContents(exSize);
-			}
-			int exceptionNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.ExceptionsName);
-			this.contents[this.contentsOffset++] = (byte) (exceptionNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) exceptionNameIndex;
-			// The attribute length = length * 2 + 2 in case of a exception attribute
-			int attributeLength = length * 2 + 2;
-			this.contents[this.contentsOffset++] = (byte) (attributeLength >> 24);
-			this.contents[this.contentsOffset++] = (byte) (attributeLength >> 16);
-			this.contents[this.contentsOffset++] = (byte) (attributeLength >> 8);
-			this.contents[this.contentsOffset++] = (byte) attributeLength;
-			this.contents[this.contentsOffset++] = (byte) (length >> 8);
-			this.contents[this.contentsOffset++] = (byte) length;
-			for (int i = 0; i < length; i++) {
-				int exceptionIndex = this.constantPool.literalIndexForType(thrownsExceptions[i]);
-				this.contents[this.contentsOffset++] = (byte) (exceptionIndex >> 8);
-				this.contents[this.contentsOffset++] = (byte) exceptionIndex;
-			}
-			attributeNumber++;
+			attributesNumber += generateExceptionsAttribute(thrownsExceptions);
 		}
 		if (methodBinding.isDeprecated()) {
 			// Deprecated attribute
-			// Check that there is enough space to write the deprecated attribute
-			if (this.contentsOffset + 6 >= this.contents.length) {
-				resizeContents(6);
-			}
-			int deprecatedAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.DeprecatedName);
-			this.contents[this.contentsOffset++] = (byte) (deprecatedAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) deprecatedAttributeNameIndex;
-			// the length of a deprecated attribute is equals to 0
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-
-			attributeNumber++;
+			attributesNumber += generateDeprecatedAttribute();
 		}
 		if (this.targetJDK < ClassFileConstants.JDK1_5) {
 			if (methodBinding.isSynthetic()) {
-				// Synthetic attribute
-				// Check that there is enough space to write the deprecated attribute
-				if (this.contentsOffset + 6 >= this.contents.length) {
-					resizeContents(6);
-				}
-				int syntheticAttributeNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
-				this.contents[this.contentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
-				this.contents[this.contentsOffset++] = (byte) syntheticAttributeNameIndex;
-				// the length of a synthetic attribute is equals to 0
-				this.contents[this.contentsOffset++] = 0;
-				this.contents[this.contentsOffset++] = 0;
-				this.contents[this.contentsOffset++] = 0;
-				this.contents[this.contentsOffset++] = 0;
-
-				attributeNumber++;
+				attributesNumber += generateSyntheticAttribute();
 			}
 			if (methodBinding.isVarargs()) {
-				/*
-				 * handle of the target jsr14 for varargs in the source
-				 * Varargs attribute
-				 * Check that there is enough space to write the deprecated attribute
-				 */
-				if (this.contentsOffset + 6 >= this.contents.length) {
-					resizeContents(6);
-				}
-				int varargsAttributeNameIndex =
-					this.constantPool.literalIndex(AttributeNamesConstants.VarargsName);
-				this.contents[this.contentsOffset++] = (byte) (varargsAttributeNameIndex >> 8);
-				this.contents[this.contentsOffset++] = (byte) varargsAttributeNameIndex;
-				// the length of a varargs attribute is equals to 0
-				this.contents[this.contentsOffset++] = 0;
-				this.contents[this.contentsOffset++] = 0;
-				this.contents[this.contentsOffset++] = 0;
-				this.contents[this.contentsOffset++] = 0;
-
-				attributeNumber++;
+				attributesNumber += generateVarargsAttribute();
 			}
 		}
 		// add signature attribute
 		char[] genericSignature = methodBinding.genericSignature();
 		if (genericSignature != null) {
-			// check that there is enough space to write all the bytes for the field info corresponding
-			// to the @fieldBinding
-			if (this.contentsOffset + 8 >= this.contents.length) {
-				resizeContents(8);
-			}
-			int signatureAttributeNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.SignatureName);
-			this.contents[this.contentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) signatureAttributeNameIndex;
-			// the length of a signature attribute is equals to 2
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 0;
-			this.contents[this.contentsOffset++] = 2;
-			int signatureIndex =
-				this.constantPool.literalIndex(genericSignature);
-			this.contents[this.contentsOffset++] = (byte) (signatureIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) signatureIndex;
-			attributeNumber++;
+			attributesNumber += generateSignatureAttribute(genericSignature);
 		}
 		if (this.targetJDK >= ClassFileConstants.JDK1_4) {
 			AbstractMethodDeclaration methodDeclaration = methodBinding.sourceMethod();
 			if (methodDeclaration != null) {
 				Annotation[] annotations = methodDeclaration.annotations;
 				if (annotations != null) {
-					attributeNumber += generateRuntimeAnnotations(annotations);
+					attributesNumber += generateRuntimeAnnotations(annotations);
 				}
 				if ((methodBinding.tagBits & TagBits.HasParameterAnnotations) != 0) {
 					Argument[] arguments = methodDeclaration.arguments;
 					if (arguments != null) {
-						attributeNumber += generateRuntimeAnnotationsForParameters(arguments);
+						attributesNumber += generateRuntimeAnnotationsForParameters(arguments);
 					}
 				}
 			}
@@ -6416,32 +2780,14 @@
 		if ((methodBinding.tagBits & TagBits.HasMissingType) != 0) {
 			this.missingTypes = methodBinding.collectMissingTypes(this.missingTypes);
 		}
-		return attributeNumber;
+		return attributesNumber;
 	}
-
-	public int generateMethodInfoAttribute(MethodBinding methodBinding, AnnotationMethodDeclaration declaration) {
-		int attributesNumber = generateMethodInfoAttribute(methodBinding);
+	public int generateMethodInfoAttributes(MethodBinding methodBinding, AnnotationMethodDeclaration declaration) {
+		int attributesNumber = generateMethodInfoAttributes(methodBinding);
 		int attributeOffset = this.contentsOffset;
 		if ((declaration.modifiers & ClassFileConstants.AccAnnotationDefault) != 0) {
 			// add an annotation default attribute
-			int annotationDefaultNameIndex =
-				this.constantPool.literalIndex(AttributeNamesConstants.AnnotationDefaultName);
-			this.contents[this.contentsOffset++] = (byte) (annotationDefaultNameIndex >> 8);
-			this.contents[this.contentsOffset++] = (byte) annotationDefaultNameIndex;
-			int attributeLengthOffset = this.contentsOffset;
-			this.contentsOffset += 4;
-			if (this.contentsOffset + 4 >= this.contents.length) {
-				resizeContents(4);
-			}
-			generateElementValue(declaration.defaultValue, declaration.binding.returnType, attributeOffset);
-			if (this.contentsOffset != attributeOffset) {
-				int attributeLength = this.contentsOffset - attributeLengthOffset - 4;
-				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 24);
-				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 16);
-				this.contents[attributeLengthOffset++] = (byte) (attributeLength >> 8);
-				this.contents[attributeLengthOffset++] = (byte) attributeLength;
-				attributesNumber++;
-			}
+			attributesNumber += generateAnnotationDefaultAttribute(declaration, attributeOffset);
 		}
 		return attributesNumber;
 	}
@@ -6458,6 +2804,7 @@
 	public void generateMethodInfoHeader(MethodBinding methodBinding) {
 		generateMethodInfoHeader(methodBinding, methodBinding.modifiers);
 	}
+
 	/**
 	 * INTERNAL USE-ONLY
 	 * That method generates the header of a method info:
@@ -6627,9 +2974,9 @@
 
 		for (int i = 0; i < length; i++) {
 			Annotation annotation = annotations[i];
-			if (isRuntimeInvisible(annotation)) {
+			if (annotation.isRuntimeInvisible()) {
 				invisibleAnnotationsCounter++;
-			} else if (isRuntimeVisible(annotation)) {
+			} else if (annotation.isRuntimeVisible()) {
 				visibleAnnotationsCounter++;
 			}
 		}
@@ -6655,7 +3002,7 @@
 			loop: for (int i = 0; i < length; i++) {
 				if (invisibleAnnotationsCounter == 0) break loop;
 				Annotation annotation = annotations[i];
-				if (isRuntimeInvisible(annotation)) {
+				if (annotation.isRuntimeInvisible()) {
 					int currentAnnotationOffset = this.contentsOffset;
 					generateAnnotation(annotation, currentAnnotationOffset);
 					invisibleAnnotationsCounter--;
@@ -6702,7 +3049,7 @@
 			loop: for (int i = 0; i < length; i++) {
 				if (visibleAnnotationsCounter == 0) break loop;
 				Annotation annotation = annotations[i];
-				if (isRuntimeVisible(annotation)) {
+				if (annotation.isRuntimeVisible()) {
 					visibleAnnotationsCounter--;
 					int currentAnnotationOffset = this.contentsOffset;
 					generateAnnotation(annotation, currentAnnotationOffset);
@@ -6728,7 +3075,6 @@
 		}
 		return attributesNumber;
 	}
-
 	private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
 		final int argumentsLength = arguments.length;
 		final int VISIBLE_INDEX = 0;
@@ -6742,10 +3088,10 @@
 			if (annotations != null) {
 				for (int j = 0, max2 = annotations.length; j < max2; j++) {
 					Annotation annotation = annotations[j];
-					if (isRuntimeInvisible(annotation)) {
+					if (annotation.isRuntimeInvisible()) {
 						annotationsCounters[i][INVISIBLE_INDEX]++;
 						invisibleParametersAnnotationsCounter++;
-					} else if (isRuntimeVisible(annotation)) {
+					} else if (annotation.isRuntimeVisible()) {
 						annotationsCounters[i][VISIBLE_INDEX]++;
 						visibleParametersAnnotationsCounter++;
 					}
@@ -6785,7 +3131,7 @@
 						Annotation[] annotations = argument.annotations;
 						for (int j = 0, max = annotations.length; j < max; j++) {
 							Annotation annotation = annotations[j];
-							if (isRuntimeInvisible(annotation)) {
+							if (annotation.isRuntimeInvisible()) {
 								int currentAnnotationOffset = this.contentsOffset;
 								generateAnnotation(annotation, currentAnnotationOffset);
 								if (this.contentsOffset != currentAnnotationOffset) {
@@ -6843,7 +3189,7 @@
 						Annotation[] annotations = argument.annotations;
 						for (int j = 0, max = annotations.length; j < max; j++) {
 							Annotation annotation = annotations[j];
-							if (isRuntimeVisible(annotation)) {
+							if (annotation.isRuntimeVisible()) {
 								int currentAnnotationOffset = this.contentsOffset;
 								generateAnnotation(annotation, currentAnnotationOffset);
 								if (this.contentsOffset != currentAnnotationOffset) {
@@ -6873,6 +3219,629 @@
 		return attributesNumber;
 	}
 
+	private int generateSignatureAttribute(char[] genericSignature) {
+		int localContentsOffset = this.contentsOffset;
+		if (localContentsOffset + 8 >= this.contents.length) {
+			resizeContents(8);
+		}
+		int signatureAttributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.SignatureName);
+		this.contents[localContentsOffset++] = (byte) (signatureAttributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) signatureAttributeNameIndex;
+		// the length of a signature attribute is equals to 2
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 2;
+		int signatureIndex =
+			this.constantPool.literalIndex(genericSignature);
+		this.contents[localContentsOffset++] = (byte) (signatureIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) signatureIndex;
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+
+	private int generateSourceAttribute(String fullFileName) {
+		int localContentsOffset = this.contentsOffset;
+		// check that there is enough space to write all the bytes for the field info corresponding
+		// to the @fieldBinding
+		if (localContentsOffset + 8 >= this.contents.length) {
+			resizeContents(8);
+		}
+		int sourceAttributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.SourceName);
+		this.contents[localContentsOffset++] = (byte) (sourceAttributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) sourceAttributeNameIndex;
+		// The length of a source file attribute is 2. This is a fixed-length
+		// attribute
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 2;
+		// write the source file name
+		int fileNameIndex = this.constantPool.literalIndex(fullFileName.toCharArray());
+		this.contents[localContentsOffset++] = (byte) (fileNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) fileNameIndex;
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+	private int generateStackMapAttribute(
+			MethodBinding methodBinding,
+			int code_length,
+			int codeAttributeOffset,
+			int max_locals,
+			boolean isClinit) {
+		int attributesNumber = 0;
+		int localContentsOffset = this.contentsOffset;
+		StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
+		stackMapFrameCodeStream.removeFramePosition(code_length);
+		if (stackMapFrameCodeStream.hasFramePositions()) {
+			ArrayList frames = new ArrayList();
+			traverse(isClinit ? null : methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
+			int numberOfFrames = frames.size();
+			if (numberOfFrames > 1) {
+				int stackMapTableAttributeOffset = localContentsOffset;
+				// add the stack map table attribute
+				if (localContentsOffset + 8 >= this.contents.length) {
+					resizeContents(8);
+				}
+				int stackMapAttributeNameIndex =
+					this.constantPool.literalIndex(AttributeNamesConstants.StackMapName);
+				this.contents[localContentsOffset++] = (byte) (stackMapAttributeNameIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) stackMapAttributeNameIndex;
+
+				int stackMapAttributeLengthOffset = localContentsOffset;
+				// generate the attribute
+				localContentsOffset += 4;
+				if (localContentsOffset + 4 >= this.contents.length) {
+					resizeContents(4);
+				}
+				int numberOfFramesOffset = localContentsOffset;
+				localContentsOffset += 2;
+				if (localContentsOffset + 2 >= this.contents.length) {
+					resizeContents(2);
+				}
+				StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
+				for (int j = 1; j < numberOfFrames; j++) {
+					// select next frame
+					currentFrame = (StackMapFrame) frames.get(j);
+					// generate current frame
+					// need to find differences between the current frame and the previous frame
+					int frameOffset = currentFrame.pc;
+					// FULL_FRAME
+					if (localContentsOffset + 5 >= this.contents.length) {
+						resizeContents(5);
+					}
+					this.contents[localContentsOffset++] = (byte) (frameOffset >> 8);
+					this.contents[localContentsOffset++] = (byte) frameOffset;
+					int numberOfLocalOffset = localContentsOffset;
+					localContentsOffset += 2; // leave two spots for number of locals
+					int numberOfLocalEntries = 0;
+					int numberOfLocals = currentFrame.getNumberOfLocals();
+					int numberOfEntries = 0;
+					int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
+					for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
+						if (localContentsOffset + 3 >= this.contents.length) {
+							resizeContents(3);
+						}
+						VerificationTypeInfo info = currentFrame.locals[i];
+						if (info == null) {
+							this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+						} else {
+							switch(info.id()) {
+								case T_boolean :
+								case T_byte :
+								case T_char :
+								case T_int :
+								case T_short :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+									break;
+								case T_float :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+									break;
+								case T_long :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+									i++;
+									break;
+								case T_double :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+									i++;
+									break;
+								case T_null :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+									break;
+								default:
+									this.contents[localContentsOffset++] = (byte) info.tag;
+								switch (info.tag) {
+									case VerificationTypeInfo.ITEM_UNINITIALIZED :
+										int offset = info.offset;
+										this.contents[localContentsOffset++] = (byte) (offset >> 8);
+										this.contents[localContentsOffset++] = (byte) offset;
+										break;
+									case VerificationTypeInfo.ITEM_OBJECT :
+										int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+										this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+										this.contents[localContentsOffset++] = (byte) indexForType;
+								}
+							}
+							numberOfLocalEntries++;
+						}
+						numberOfEntries++;
+					}
+					if (localContentsOffset + 4 >= this.contents.length) {
+						resizeContents(4);
+					}
+					this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
+					this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
+					int numberOfStackItems = currentFrame.numberOfStackItems;
+					this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
+					this.contents[localContentsOffset++] = (byte) numberOfStackItems;
+					for (int i = 0; i < numberOfStackItems; i++) {
+						if (localContentsOffset + 3 >= this.contents.length) {
+							resizeContents(3);
+						}
+						VerificationTypeInfo info = currentFrame.stackItems[i];
+						if (info == null) {
+							this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+						} else {
+							switch(info.id()) {
+								case T_boolean :
+								case T_byte :
+								case T_char :
+								case T_int :
+								case T_short :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+									break;
+								case T_float :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+									break;
+								case T_long :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+									break;
+								case T_double :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+									break;
+								case T_null :
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+									break;
+								default:
+									this.contents[localContentsOffset++] = (byte) info.tag;
+								switch (info.tag) {
+									case VerificationTypeInfo.ITEM_UNINITIALIZED :
+										int offset = info.offset;
+										this.contents[localContentsOffset++] = (byte) (offset >> 8);
+										this.contents[localContentsOffset++] = (byte) offset;
+										break;
+									case VerificationTypeInfo.ITEM_OBJECT :
+										int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+										this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+										this.contents[localContentsOffset++] = (byte) indexForType;
+								}
+							}
+						}
+					}
+				}
+
+				numberOfFrames--;
+				if (numberOfFrames != 0) {
+					this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
+					this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
+
+					int attributeLength = localContentsOffset - stackMapAttributeLengthOffset - 4;
+					this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 24);
+					this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 16);
+					this.contents[stackMapAttributeLengthOffset++] = (byte) (attributeLength >> 8);
+					this.contents[stackMapAttributeLengthOffset] = (byte) attributeLength;
+					attributesNumber++;
+				} else {
+					localContentsOffset = stackMapTableAttributeOffset;
+				}
+			}
+		}
+		this.contentsOffset = localContentsOffset;
+		return attributesNumber;
+	}
+
+	private int generateStackMapTableAttribute(
+			MethodBinding methodBinding,
+			int code_length,
+			int codeAttributeOffset,
+			int max_locals,
+			boolean isClinit) {
+		int attributesNumber = 0;
+		int localContentsOffset = this.contentsOffset;
+		StackMapFrameCodeStream stackMapFrameCodeStream = (StackMapFrameCodeStream) this.codeStream;
+		stackMapFrameCodeStream.removeFramePosition(code_length);
+		if (stackMapFrameCodeStream.hasFramePositions()) {
+			ArrayList frames = new ArrayList();
+			traverse(isClinit ? null: methodBinding, max_locals, this.contents, codeAttributeOffset + 14, code_length, frames, isClinit);
+			int numberOfFrames = frames.size();
+			if (numberOfFrames > 1) {
+				int stackMapTableAttributeOffset = localContentsOffset;
+				// add the stack map table attribute
+				if (localContentsOffset + 8 >= this.contents.length) {
+					resizeContents(8);
+				}
+				int stackMapTableAttributeNameIndex =
+					this.constantPool.literalIndex(AttributeNamesConstants.StackMapTableName);
+				this.contents[localContentsOffset++] = (byte) (stackMapTableAttributeNameIndex >> 8);
+				this.contents[localContentsOffset++] = (byte) stackMapTableAttributeNameIndex;
+
+				int stackMapTableAttributeLengthOffset = localContentsOffset;
+				// generate the attribute
+				localContentsOffset += 4;
+				if (localContentsOffset + 4 >= this.contents.length) {
+					resizeContents(4);
+				}
+				int numberOfFramesOffset = localContentsOffset;
+				localContentsOffset += 2;
+				if (localContentsOffset + 2 >= this.contents.length) {
+					resizeContents(2);
+				}
+				StackMapFrame currentFrame = (StackMapFrame) frames.get(0);
+				StackMapFrame prevFrame = null;
+				for (int j = 1; j < numberOfFrames; j++) {
+					// select next frame
+					prevFrame = currentFrame;
+					currentFrame = (StackMapFrame) frames.get(j);
+					// generate current frame
+					// need to find differences between the current frame and the previous frame
+					int offsetDelta = currentFrame.getOffsetDelta(prevFrame);
+					switch (currentFrame.getFrameType(prevFrame)) {
+						case StackMapFrame.APPEND_FRAME :
+							if (localContentsOffset + 3 >= this.contents.length) {
+								resizeContents(3);
+							}
+							int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame);
+							this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals);
+							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
+							this.contents[localContentsOffset++] = (byte) offsetDelta;
+							int index = currentFrame.getIndexOfDifferentLocals(numberOfDifferentLocals);
+							int numberOfLocals = currentFrame.getNumberOfLocals();
+							for (int i = index; i < currentFrame.locals.length && numberOfDifferentLocals > 0; i++) {
+								if (localContentsOffset + 6 >= this.contents.length) {
+									resizeContents(6);
+								}
+								VerificationTypeInfo info = currentFrame.locals[i];
+								if (info == null) {
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+								} else {
+									switch(info.id()) {
+										case T_boolean :
+										case T_byte :
+										case T_char :
+										case T_int :
+										case T_short :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+											break;
+										case T_float :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+											break;
+										case T_long :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+											i++;
+											break;
+										case T_double :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+											i++;
+											break;
+										case T_null :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+											break;
+										default:
+											this.contents[localContentsOffset++] = (byte) info.tag;
+											switch (info.tag) {
+												case VerificationTypeInfo.ITEM_UNINITIALIZED :
+													int offset = info.offset;
+													this.contents[localContentsOffset++] = (byte) (offset >> 8);
+													this.contents[localContentsOffset++] = (byte) offset;
+													break;
+												case VerificationTypeInfo.ITEM_OBJECT :
+													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+													this.contents[localContentsOffset++] = (byte) indexForType;
+											}
+									}
+									numberOfDifferentLocals--;
+								}
+							}
+							break;
+						case StackMapFrame.SAME_FRAME :
+							if (localContentsOffset + 1 >= this.contents.length) {
+								resizeContents(1);
+							}
+							this.contents[localContentsOffset++] = (byte) offsetDelta;
+							break;
+						case StackMapFrame.SAME_FRAME_EXTENDED :
+							if (localContentsOffset + 3 >= this.contents.length) {
+								resizeContents(3);
+							}
+							this.contents[localContentsOffset++] = (byte) 251;
+							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
+							this.contents[localContentsOffset++] = (byte) offsetDelta;
+							break;
+						case StackMapFrame.CHOP_FRAME :
+							if (localContentsOffset + 3 >= this.contents.length) {
+								resizeContents(3);
+							}
+							numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame);
+							this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals);
+							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
+							this.contents[localContentsOffset++] = (byte) offsetDelta;
+							break;
+						case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS :
+							if (localContentsOffset + 4 >= this.contents.length) {
+								resizeContents(4);
+							}
+							this.contents[localContentsOffset++] = (byte) (offsetDelta + 64);
+							if (currentFrame.stackItems[0] == null) {
+								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+							} else {
+								switch(currentFrame.stackItems[0].id()) {
+									case T_boolean :
+									case T_byte :
+									case T_char :
+									case T_int :
+									case T_short :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+										break;
+									case T_float :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+										break;
+									case T_long :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+										break;
+									case T_double :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+										break;
+									case T_null :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+										break;
+									default:
+										VerificationTypeInfo info = currentFrame.stackItems[0];
+										byte tag = (byte) info.tag;
+										this.contents[localContentsOffset++] = tag;
+										switch (tag) {
+											case VerificationTypeInfo.ITEM_UNINITIALIZED :
+												int offset = info.offset;
+												this.contents[localContentsOffset++] = (byte) (offset >> 8);
+												this.contents[localContentsOffset++] = (byte) offset;
+												break;
+											case VerificationTypeInfo.ITEM_OBJECT :
+												int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+												this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+												this.contents[localContentsOffset++] = (byte) indexForType;
+										}
+								}
+							}
+							break;
+						case StackMapFrame.SAME_LOCALS_1_STACK_ITEMS_EXTENDED :
+							if (localContentsOffset + 6 >= this.contents.length) {
+								resizeContents(6);
+							}
+							this.contents[localContentsOffset++] = (byte) 247;
+							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
+							this.contents[localContentsOffset++] = (byte) offsetDelta;
+							if (currentFrame.stackItems[0] == null) {
+								this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+							} else {
+								switch(currentFrame.stackItems[0].id()) {
+									case T_boolean :
+									case T_byte :
+									case T_char :
+									case T_int :
+									case T_short :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+										break;
+									case T_float :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+										break;
+									case T_long :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+										break;
+									case T_double :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+										break;
+									case T_null :
+										this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+										break;
+									default:
+										VerificationTypeInfo info = currentFrame.stackItems[0];
+										byte tag = (byte) info.tag;
+										this.contents[localContentsOffset++] = tag;
+										switch (tag) {
+											case VerificationTypeInfo.ITEM_UNINITIALIZED :
+												int offset = info.offset;
+												this.contents[localContentsOffset++] = (byte) (offset >> 8);
+												this.contents[localContentsOffset++] = (byte) offset;
+												break;
+											case VerificationTypeInfo.ITEM_OBJECT :
+												int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+												this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+												this.contents[localContentsOffset++] = (byte) indexForType;
+										}
+								}
+							}
+							break;
+						default :
+							// FULL_FRAME
+							if (localContentsOffset + 5 >= this.contents.length) {
+								resizeContents(5);
+							}
+							this.contents[localContentsOffset++] = (byte) 255;
+							this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8);
+							this.contents[localContentsOffset++] = (byte) offsetDelta;
+							int numberOfLocalOffset = localContentsOffset;
+							localContentsOffset += 2; // leave two spots for number of locals
+							int numberOfLocalEntries = 0;
+							numberOfLocals = currentFrame.getNumberOfLocals();
+							int numberOfEntries = 0;
+							int localsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length;
+							for (int i = 0; i < localsLength && numberOfLocalEntries < numberOfLocals; i++) {
+								if (localContentsOffset + 3 >= this.contents.length) {
+									resizeContents(3);
+								}
+								VerificationTypeInfo info = currentFrame.locals[i];
+								if (info == null) {
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+								} else {
+									switch(info.id()) {
+										case T_boolean :
+										case T_byte :
+										case T_char :
+										case T_int :
+										case T_short :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+											break;
+										case T_float :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+											break;
+										case T_long :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+											i++;
+											break;
+										case T_double :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+											i++;
+											break;
+										case T_null :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+											break;
+										default:
+											this.contents[localContentsOffset++] = (byte) info.tag;
+											switch (info.tag) {
+												case VerificationTypeInfo.ITEM_UNINITIALIZED :
+													int offset = info.offset;
+													this.contents[localContentsOffset++] = (byte) (offset >> 8);
+													this.contents[localContentsOffset++] = (byte) offset;
+													break;
+												case VerificationTypeInfo.ITEM_OBJECT :
+													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+													this.contents[localContentsOffset++] = (byte) indexForType;
+											}
+									}
+									numberOfLocalEntries++;
+								}
+								numberOfEntries++;
+							}
+							if (localContentsOffset + 4 >= this.contents.length) {
+								resizeContents(4);
+							}
+							this.contents[numberOfLocalOffset++] = (byte) (numberOfEntries >> 8);
+							this.contents[numberOfLocalOffset] = (byte) numberOfEntries;
+							int numberOfStackItems = currentFrame.numberOfStackItems;
+							this.contents[localContentsOffset++] = (byte) (numberOfStackItems >> 8);
+							this.contents[localContentsOffset++] = (byte) numberOfStackItems;
+							for (int i = 0; i < numberOfStackItems; i++) {
+								if (localContentsOffset + 3 >= this.contents.length) {
+									resizeContents(3);
+								}
+								VerificationTypeInfo info = currentFrame.stackItems[i];
+								if (info == null) {
+									this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_TOP;
+								} else {
+									switch(info.id()) {
+										case T_boolean :
+										case T_byte :
+										case T_char :
+										case T_int :
+										case T_short :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_INTEGER;
+											break;
+										case T_float :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_FLOAT;
+											break;
+										case T_long :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_LONG;
+											break;
+										case T_double :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_DOUBLE;
+											break;
+										case T_null :
+											this.contents[localContentsOffset++] = (byte) VerificationTypeInfo.ITEM_NULL;
+											break;
+										default:
+											this.contents[localContentsOffset++] = (byte) info.tag;
+											switch (info.tag) {
+												case VerificationTypeInfo.ITEM_UNINITIALIZED :
+													int offset = info.offset;
+													this.contents[localContentsOffset++] = (byte) (offset >> 8);
+													this.contents[localContentsOffset++] = (byte) offset;
+													break;
+												case VerificationTypeInfo.ITEM_OBJECT :
+													int indexForType = this.constantPool.literalIndexForType(info.constantPoolName());
+													this.contents[localContentsOffset++] = (byte) (indexForType >> 8);
+													this.contents[localContentsOffset++] = (byte) indexForType;
+											}
+									}
+								}
+							}
+					}
+				}
+
+				numberOfFrames--;
+				if (numberOfFrames != 0) {
+					this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);
+					this.contents[numberOfFramesOffset] = (byte) numberOfFrames;
+
+					int attributeLength = localContentsOffset - stackMapTableAttributeLengthOffset - 4;
+					this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 24);
+					this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 16);
+					this.contents[stackMapTableAttributeLengthOffset++] = (byte) (attributeLength >> 8);
+					this.contents[stackMapTableAttributeLengthOffset] = (byte) attributeLength;
+					attributesNumber++;
+				} else {
+					localContentsOffset = stackMapTableAttributeOffset;
+				}
+			}
+		}
+		this.contentsOffset = localContentsOffset;
+		return attributesNumber;
+	}
+
+	private int generateSyntheticAttribute() {
+		int localContentsOffset = this.contentsOffset;
+		if (localContentsOffset + 6 >= this.contents.length) {
+			resizeContents(6);
+		}
+		int syntheticAttributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.SyntheticName);
+		this.contents[localContentsOffset++] = (byte) (syntheticAttributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) syntheticAttributeNameIndex;
+		// the length of a synthetic attribute is equals to 0
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+
+	private int generateVarargsAttribute() {
+		int localContentsOffset = this.contentsOffset;
+		/*
+		 * handle of the target jsr14 for varargs in the source
+		 * Varargs attribute
+		 * Check that there is enough space to write the attribute
+		 */
+		if (localContentsOffset + 6 >= this.contents.length) {
+			resizeContents(6);
+		}
+		int varargsAttributeNameIndex =
+			this.constantPool.literalIndex(AttributeNamesConstants.VarargsName);
+		this.contents[localContentsOffset++] = (byte) (varargsAttributeNameIndex >> 8);
+		this.contents[localContentsOffset++] = (byte) varargsAttributeNameIndex;
+		// the length of a varargs attribute is equals to 0
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+		this.contents[localContentsOffset++] = 0;
+
+		this.contentsOffset = localContentsOffset;
+		return 1;
+	}
+
 	/**
 	 * EXTERNAL API
 	 * Answer the actual bytes of the class file
@@ -7017,6 +3986,10 @@
 		if (aType.isAnonymousType()) {
 			accessFlags &= ~ClassFileConstants.AccFinal;
 		}
+		int finalAbstract = ClassFileConstants.AccFinal | ClassFileConstants.AccAbstract;
+		if ((accessFlags & finalAbstract) == finalAbstract) {
+			accessFlags &= ~finalAbstract;
+		}
 		this.enclosingClassFile = parentClassFile;
 		// innerclasses get their names computed at code gen time
 
@@ -7252,31 +4225,6 @@
 			}
 		}
 	}
-
-	private boolean isRuntimeInvisible(Annotation annotation) {
-		final TypeBinding annotationBinding = annotation.resolvedType;
-		if (annotationBinding == null) {
-			return false;
-		}
-		long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
-		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
-			return true; // by default the retention is CLASS
-
-		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
-	}
-
-	private boolean isRuntimeVisible(Annotation annotation) {
-		final TypeBinding annotationBinding = annotation.resolvedType;
-		if (annotationBinding == null) {
-			return false;
-		}
-		long metaTagBits = annotationBinding.getAnnotationTagBits();
-		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
-			return false; // by default the retention is CLASS
-
-		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
-	}
-
 	/**
 	 * INTERNAL USE-ONLY
 	 * Returns the most enclosing classfile of the receiver. This is used know to store the constant pool name
@@ -8501,10 +5449,10 @@
 					int classNameLength = className.length;
 					if (className[0] != '[') {
 						// this is a type name (class or interface). So we add appropriate '[', 'L' and ';'.
-					System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 3]), 2, classNameLength);
-					constantPoolName[0] = '[';
-					constantPoolName[1] = 'L';
-					constantPoolName[classNameLength + 2] = ';';
+						System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 3]), 2, classNameLength);
+						constantPoolName[0] = '[';
+						constantPoolName[1] = 'L';
+						constantPoolName[classNameLength + 2] = ';';
 					} else {
 						// if class name is already an array, we just need to add one dimension
 						System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 1]), 1, classNameLength);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
index a409d4b..f1804a5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -60,6 +61,12 @@
 			}
 		}
 		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
+		if ((this.left.implicitConversion & TypeIds.UNBOXING) != 0) {
+			this.left.checkNPE(currentScope, flowContext, flowInfo);
+		}
+		if ((this.right.implicitConversion & TypeIds.UNBOXING) != 0) {
+			this.right.checkNPE(currentScope, flowContext, flowInfo);
+		}
 		FlowInfo mergedInfo = FlowInfo.conditional(
 				rightInfo.safeInitsWhenTrue(),
 				leftInfo.initsWhenFalse().unconditionalInits().mergedWith(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index fdc3fd6..e353aa5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -402,7 +402,7 @@
 
 		classFile.generateMethodInfoHeader(this.binding);
 		int methodAttributeOffset = classFile.contentsOffset;
-		int attributeNumber = classFile.generateMethodInfoAttribute(this.binding);
+		int attributeNumber = classFile.generateMethodInfoAttributes(this.binding);
 //{ObjectTeams: write OT-specific byte code attributes
         if (this.model != null)
             attributeNumber += this.model.writeAttributes(classFile);
@@ -477,7 +477,7 @@
 		} else {
 			checkArgumentsSize();
 		}
-		classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+		classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
 	}
 //{ObjectTeams: recording byte code
 	public void maybeRecordByteCode(ClassFile classFile, int methodAttributeOffset) {
@@ -512,7 +512,7 @@
 
 	private void checkArgumentsSize() {
 		TypeBinding[] parameters = this.binding.parameters;
-		int size = 1; // an abstact method or a native method cannot be static
+		int size = 1; // an abstract method or a native method cannot be static
 		for (int i = 0, max = parameters.length; i < max; i++) {
 			switch(parameters[i].id) {
 				case TypeIds.T_long :
@@ -755,7 +755,9 @@
 // SH}
 			}
 		} else if ((this.bits & UndocumentedEmptyBlock) != 0) {
-			this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd+1);
+			if (!this.isConstructor() || this.arguments != null) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=319626
+				this.scope.problemReporter().undocumentedEmptyBlock(this.bodyStart-1, this.bodyEnd+1);
+			}
 		}
 //{ObjectTeams:
 	  } finally {
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 42f6113..892f69a 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
@@ -8,7 +8,9 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     Stephan Herrmann - Contribution for bug 236385
+ *     Stephan Herrmann - Contributions for 
+ *     						bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ *     						bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -79,6 +81,9 @@
 				this.arguments[i]
 					.analyseCode(currentScope, flowContext, flowInfo)
 					.unconditionalInits();
+			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
+				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
+			}
 		}
 	}
 	// record some dependency information for exception types
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 c169b9a..6044b02 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -176,6 +176,30 @@
 		return this.compilerAnnotation;
 	}
 
+	public boolean isRuntimeInvisible() {
+		final TypeBinding annotationBinding = this.resolvedType;
+		if (annotationBinding == null) {
+			return false;
+		}
+		long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
+		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
+			return true; // by default the retention is CLASS
+
+		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationClassRetention;
+	}
+
+	public boolean isRuntimeVisible() {
+		final TypeBinding annotationBinding = this.resolvedType;
+		if (annotationBinding == null) {
+			return false;
+		}
+		long metaTagBits = annotationBinding.getAnnotationTagBits();
+		if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)
+			return false; // by default the retention is CLASS
+
+		return (metaTagBits & TagBits.AnnotationRetentionMASK) == TagBits.AnnotationRuntimeRetention;
+	}
+
 	public abstract MemberValuePair[] memberValuePairs();
 
 	public StringBuffer printExpression(int indent, StringBuffer output) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
index 52a2fc8..8860ec6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -32,8 +32,8 @@
 	public void generateCode(ClassFile classFile) {
 		classFile.generateMethodInfoHeader(this.binding);
 		int methodAttributeOffset = classFile.contentsOffset;
-		int attributeNumber = classFile.generateMethodInfoAttribute(this.binding, this);
-		classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+		int attributeNumber = classFile.generateMethodInfoAttributes(this.binding, this);
+		classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
 	}
 
 	public boolean isAnnotationMethod() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
index 4e93750..8a8a683 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -41,6 +42,9 @@
 			Expression dim;
 			if ((dim = this.dimensions[i]) != null) {
 				flowInfo = dim.analyseCode(currentScope, flowContext, flowInfo);
+				if ((dim.implicitConversion & TypeIds.UNBOXING) != 0) {
+					dim.checkNPE(currentScope, flowContext, flowInfo);
+				}
 			}
 		}
 		if (this.initializer != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
index bab16b3..d1887e2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -42,6 +43,9 @@
 	this.preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
 
 	Constant cst = this.assertExpression.optimizedBooleanConstant();
+	if ((this.assertExpression.implicitConversion & TypeIds.UNBOXING) != 0) {
+		this.assertExpression.checkNPE(currentScope, flowContext, flowInfo);
+	}
 	boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true;
 	boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false;
 	
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 f0711af..b5c5439 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -9,6 +9,8 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Genady Beriozkin - added support for reporting assignment with no effect
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     												and bug 292478 - Report potentially null across variable assignment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -69,6 +71,9 @@
 // a field reference, a blank final field reference, a field of an enclosing instance or
 // just a local variable.
 	LocalVariableBinding local = this.lhs.localVariableBinding();
+	if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
+		this.expression.checkNPE(currentScope, flowContext, flowInfo);
+	}
 	int nullStatus = this.expression.nullStatus(flowInfo);
 	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
 		if (nullStatus == FlowInfo.NULL) {
@@ -80,28 +85,9 @@
 		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
 		.unconditionalInits();
 	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
-		switch(nullStatus) {
-			case FlowInfo.NULL :
-				flowInfo.markAsDefinitelyNull(local);
-				break;
-			case FlowInfo.NON_NULL :
-				flowInfo.markAsDefinitelyNonNull(local);
-				break;
-			default:
-				flowInfo.markAsDefinitelyUnknown(local);
-		}
-		if (flowContext.initsOnFinally != null) {
-			switch(nullStatus) {
-				case FlowInfo.NULL :
-					flowContext.initsOnFinally.markAsDefinitelyNull(local);
-					break;
-				case FlowInfo.NON_NULL :
-					flowContext.initsOnFinally.markAsDefinitelyNonNull(local);
-					break;
-				default:
-					flowContext.initsOnFinally.markAsDefinitelyUnknown(local);
-			}
-		}
+		flowInfo.markNullStatus(local, nullStatus);
+		if (flowContext.initsOnFinally != null)
+			flowContext.initsOnFinally.markNullStatus(local, nullStatus);
 	}
 	return flowInfo;
 }
@@ -192,7 +178,7 @@
 	}
 	// check for assignment with no effect
 	Binding left = getDirectBinding(this.lhs);
-	if (left != null && left == getDirectBinding(this.expression)) {
+	if (left != null && !left.isVolatile() && left == getDirectBinding(this.expression)) {
 		scope.problemReporter().assignmentHasNoEffect(this, left.shortReadableName());
 	}
 //{ObjectTeams: wrap rhs type:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
index 3712e62..3c59918 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -82,8 +82,8 @@
 }
 
 public StringBuffer printStatement(int tab, StringBuffer output) {
-	printIndent(tab, output).append("break "); //$NON-NLS-1$
-	if (this.label != null) output.append(this.label);
+	printIndent(tab, output).append("break"); //$NON-NLS-1$
+	if (this.label != null) output.append(' ').append(this.label);
 	return output.append(';');
 }
 
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 7eb4c34..42bf559 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, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -53,12 +53,12 @@
 public StringBuffer printStatement(int tab, StringBuffer output) {
 	printIndent(tab, output);
 	if (this.constantExpression == null) {
-		output.append("default : "); //$NON-NLS-1$
+		output.append("default :"); //$NON-NLS-1$
 	} else {
 		output.append("case "); //$NON-NLS-1$
-		this.constantExpression.printExpression(0, output).append(" : "); //$NON-NLS-1$
+		this.constantExpression.printExpression(0, output).append(" :"); //$NON-NLS-1$
 	}
-	return output.append(';');
+	return output;
 }
 
 /**
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 aad51d2..aaf8da6 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
@@ -9,6 +9,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -139,9 +140,13 @@
 }
 
 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	return this.expression
+	FlowInfo result = this.expression
 		.analyseCode(currentScope, flowContext, flowInfo)
 		.unconditionalInits();
+	if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
+		this.expression.checkNPE(currentScope, flowContext, flowInfo);
+	}
+	return result;
 }
 
 /**
@@ -338,6 +343,7 @@
 			public void setFieldIndex(int depth){ /* ignore */}
 			public int sourceStart() { return 0; }
 			public int sourceEnd() { return 0; }
+			public TypeBinding expectedType() { return invocationSite.expectedType(); }
 		};
 		MethodBinding bindingIfNoCast;
 		if (binding.isConstructor()) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
index 069bab1..edd5f83 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java
@@ -111,6 +111,16 @@
 		this.constant = Constant.NotAConstant;
 		if ((this.targetType = this.type.resolveType(scope, true /* check bounds*/)) == null)
 			return null;
+		
+		/* https://bugs.eclipse.org/bugs/show_bug.cgi?id=320463
+		   https://bugs.eclipse.org/bugs/show_bug.cgi?id=312076
+		   JLS3 15.8.2 forbids the type named in the class literal expression from being a parameterized type.
+		   And the grammar in 18.1 disallows (where X and Y are some concrete types) constructs of the form
+		   Outer<X>.class, Outer<X>.Inner.class, Outer.Inner<X>.class, Outer<X>.Inner<Y>.class etc.
+		   Corollary wise, we should resolve the type of the class literal expression to be a raw type as
+		   class literals exist only for the raw underlying type. 
+		 */
+		this.targetType = scope.environment().convertToRawType(this.targetType, true /* force conversion of enclosing types*/);
 
 		if (this.targetType.isArrayType()) {
 			ArrayBinding arrayBinding = (ArrayBinding) this.targetType;
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 a1473e9..5f4c7f6 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
@@ -378,7 +378,7 @@
 									IrritantSet tokenIrritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
 									if (tokenIrritants != null
 											&& !tokenIrritants.areAllSet() // no complaint against @SuppressWarnings("all")
-											&& options.isAnyEnabled(tokenIrritants) // if irritant is effectevely enabled
+											&& options.isAnyEnabled(tokenIrritants) // if irritant is effectively enabled
 											&& (foundIrritants[iSuppress] == null || !foundIrritants[iSuppress].isAnySet(tokenIrritants))) { // if irritant had no matching problem
 										if (unusedWarningTokenIsWarning) {
 											int start = value.sourceStart, end = value.sourceEnd;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index 98b5330..a0241c1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for bugs 133125, 292478
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -332,8 +333,19 @@
 	if (ifTrueNullStatus == ifFalseNullStatus) {
 		return ifTrueNullStatus;
 	}
+	// is there a chance of null (or non-null)? -> potentially null etc.
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
+	int status = 0;
+	int combinedStatus = ifTrueNullStatus|ifFalseNullStatus;
+	if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
+		status |= FlowInfo.POTENTIALLY_NULL;
+	if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
+		status |= FlowInfo.POTENTIALLY_NON_NULL;
+	if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
+		status |= FlowInfo.POTENTIALLY_UNKNOWN;
+	if (status > 0)
+		return status;
 	return FlowInfo.UNKNOWN;
-	// cannot decide which branch to take, and they disagree
 }
 
 	public Constant optimizedBooleanConstant() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 7617bc8..58fb295 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -437,7 +437,7 @@
 private void internalGenerateCode(ClassScope classScope, ClassFile classFile) {
 	classFile.generateMethodInfoHeader(this.binding);
 	int methodAttributeOffset = classFile.contentsOffset;
-	int attributeNumber = classFile.generateMethodInfoAttribute(this.binding);
+	int attributeNumber = classFile.generateMethodInfoAttributes(this.binding);
 //{ObjectTeams: write OT-specific byte code attributes
     if (this.model != null)
         attributeNumber += this.model.writeAttributes(classFile);
@@ -598,7 +598,7 @@
 			((StackMapFrameCodeStream) codeStream).resetSecretLocals();
 		}
 	}
-	classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);
+	classFile.completeMethodInfo(this.binding, methodAttributeOffset, attributeNumber);
 }
 
 //{ObjectTeams: ctors are copied for roles and teams:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
index 3228d46..cf09127 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -57,6 +58,8 @@
 
 	int previousMode = flowInfo.reachMode();
 
+	FlowInfo initsOnCondition = flowInfo;
+
 	UnconditionalFlowInfo actionInfo = flowInfo.nullInfoLessUnconditionalCopy();
 	// we need to collect the contribution to nulls of the coming paths through the
 	// loop, be they falling through normally or branched to break, continue labels
@@ -72,6 +75,14 @@
 				FlowInfo.UNREACHABLE) != 0) {
 			this.continueLabel = null;
 		}
+		if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
+			initsOnCondition = flowInfo.unconditionalInits().
+									addInitializationsFrom(
+										actionInfo.mergedWith(loopingContext.initsOnContinue));
+		}
+	}
+	if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
+		this.condition.checkNPE(currentScope, flowContext, initsOnCondition);
 	}
 	/* Reset reach mode, to address following scenario.
 	 *   final blank;
@@ -101,7 +112,11 @@
 				actionInfo.addPotentialNullInfoFrom(
 				  condInfo.initsWhenTrue().unconditionalInits()));
 	}
-
+	if (loopingContext.hasEscapingExceptions()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926
+		FlowInfo loopbackFlowInfo = flowInfo.copy();
+		loopbackFlowInfo.mergedWith(condInfo.initsWhenTrue().unconditionalCopy());
+		loopingContext.simulateThrowAfterLoopBack(loopbackFlowInfo);
+	}
 	// end of loop
 	FlowInfo mergedInfo = 
 		FlowInfo.mergedOptimizedBranches(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
index 87c25cb..a9ce3fc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java
@@ -56,6 +56,9 @@
 					flowContext.recordUsingNullReference(scope, local, reference,
 							FlowContext.CAN_ONLY_NULL | FlowContext.IN_COMPARISON_NON_NULL, flowInfo);
 					initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
+					if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+						initsWhenTrue.markedAsNullOrNonNullInAssertExpression(local);
+					}
 				} else {
 					flowContext.recordUsingNullReference(scope, local, reference,
 							FlowContext.CAN_ONLY_NULL | FlowContext.IN_COMPARISON_NULL, flowInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
index 78aecab..2036f58 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -137,6 +138,9 @@
 						this.arguments[i]
 							.analyseCode(currentScope, flowContext, flowInfo)
 							.unconditionalInits();
+					if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
+						this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
+					}
 				}
 			}
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index b3b4926..b9568ec 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 292478 - Report potentially null across variable assignment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -674,8 +675,14 @@
 		}
 		flowInfo.markAsComparedEqualToNonNull(local);
 			// from thereon it is set
+		if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+			flowInfo.markedAsNullOrNonNullInAssertExpression(local);
+		}
 		if (flowContext.initsOnFinally != null) {
 			flowContext.initsOnFinally.markAsComparedEqualToNonNull(local);
+			if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+				flowContext.initsOnFinally.markedAsNullOrNonNullInAssertExpression(local);
+			}
 		}
 	}
 }
@@ -1000,13 +1007,8 @@
 	return FlowInfo.NON_NULL; // constant expression cannot be null
 
 	LocalVariableBinding local = localVariableBinding();
-	if (local != null) {
-		if (flowInfo.isDefinitelyNull(local))
-			return FlowInfo.NULL;
-		if (flowInfo.isDefinitelyNonNull(local))
-			return FlowInfo.NON_NULL;
-		return FlowInfo.UNKNOWN;
-	}
+	if (local != null)
+		return flowInfo.nullStatus(local);
 	return FlowInfo.NON_NULL;
 }
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
index 643d0b6..1409a4e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java
@@ -187,7 +187,10 @@
 			SourceTypeBinding declaringType = classScope.enclosingSourceType();
 			checkHidingSuperField: {
 				if (declaringType.superclass == null) break checkHidingSuperField;
-				FieldBinding existingVariable = classScope.findField(declaringType.superclass, this.name, this,  false /*do not resolve hidden field*/);
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=318171, find field skipping visibility checks
+				// we do the checks below ourselves, using the appropriate conditions for access check of
+				// protected members from superclasses.
+				FieldBinding existingVariable = classScope.findField(declaringType.superclass, this.name, this,  false /*do not resolve hidden field*/, true /* no visibility checks please */);
 				if (existingVariable == null) break checkHidingSuperField; // keep checking outer scenario
 				if (!existingVariable.isValidBinding())  break checkHidingSuperField; // keep checking outer scenario
 				if (existingVariable.original() == this.binding) break checkHidingSuperField; // keep checking outer scenario
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
index da75f04..86593c7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
@@ -93,6 +94,9 @@
 							new LoopingFlowContext(flowContext, flowInfo, this, null,
 								null, this.scope)),
 						condInfo);
+				if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
+					this.condition.checkNPE(currentScope, flowContext, flowInfo);
+				}
 			}
 		}
 
@@ -195,7 +199,13 @@
 			incrementContext.complainOnDeferredNullChecks(currentScope,
 				actionInfo);
 		}
-
+		if (loopingContext.hasEscapingExceptions()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926
+			FlowInfo loopbackFlowInfo = flowInfo.copy();
+			if (this.continueLabel != null) {  // we do get to the bottom 
+				loopbackFlowInfo.mergedWith(actionInfo.unconditionalCopy());
+			}
+			loopingContext.simulateThrowAfterLoopBack(loopbackFlowInfo);
+		}
 		//end of loop
 		FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
 				(loopingContext.initsOnBreak.tagBits &
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
index 4b1ce1e..711fde8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java
@@ -423,6 +423,8 @@
 				if (!this.collectionElementType.isCompatibleWith(elementType)
 						&& !this.scope.isBoxingCompatibleWith(this.collectionElementType, elementType)) {
 					this.scope.problemReporter().notCompatibleTypesErrorInForeach(this.collection, this.collectionElementType, elementType);
+				} else if (this.collectionElementType.needsUncheckedConversion(elementType)) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=321085
+				    this.scope.problemReporter().unsafeTypeConversion(this.collection, collectionType, upperScope.createArrayType(elementType, 1));
 				}
 // :giro
 				if (Config.getLoweringRequired())
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
index d7d557d..3e996d6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -57,6 +58,9 @@
 	int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
 
 	Constant cst = this.condition.optimizedBooleanConstant();
+	if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
+		this.condition.checkNPE(currentScope, flowContext, flowInfo);
+	}
 	boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
 	boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
 
@@ -65,7 +69,7 @@
 	if (isConditionOptimizedFalse) {
 		thenFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
 	}
-	FlowInfo elseFlowInfo = conditionFlowInfo.initsWhenFalse();
+	FlowInfo elseFlowInfo = conditionFlowInfo.initsWhenFalse().copy();
 	if (isConditionOptimizedTrue) {
 		elseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
 	}
@@ -130,7 +134,8 @@
 		elseFlowInfo,
 		isConditionOptimizedFalse,
 		true /*if(true){ return; }  fake-reachable(); */,
-		flowInfo);
+		flowInfo,
+		this);
 	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
 	return mergedInfo;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
index 3ce4b9e..dc2342a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -35,6 +35,8 @@
 	public int declarationSourceEnd;
 	public int modifiers; // 1.5 addition for static imports
 	public Annotation[] annotations;
+	// star end position
+	public int trailingStarPosition;
 
 //{ObjectTeams: new queries:
 	public boolean isTeam() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
index 6fdb60f..64b7e3e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java
@@ -69,6 +69,9 @@
 			unconditionalInits();
 		FlowInfo initsWhenTrue = flowInfo.copy();
 		initsWhenTrue.markAsComparedEqualToNonNull(local);
+		if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+			initsWhenTrue.markedAsNullOrNonNullInAssertExpression(local);
+		}
 		flowContext.recordUsingNullReference(currentScope, local,
 				this.expression, FlowContext.CAN_ONLY_NULL | FlowContext.IN_INSTANCEOF, flowInfo);
 		// no impact upon enclosing try context
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 a33f082..498713f 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, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and 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,18 +30,6 @@
 	this(token, s,e);
 	this.value = value;
 }
-
-public IntLiteral(int intValue) {
-	//special optimized constructor : the cst is the argument
-	//value that should not be used
-	//	tokens = null ;
-	//	sourceStart = 0;
-	//	sourceEnd = 0;
-	super(null,0,0);
-	this.constant = IntConstant.fromValue(intValue);
-	this.value = intValue;
-}
-
 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....
@@ -133,15 +121,6 @@
 			(this.source[9] == '8') &&
 			(((this.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0));
 }
-
-public StringBuffer printExpression(int indent, StringBuffer output){
-	if (this.source == null) {
-	/* special optimized IntLiteral that are created by the compiler */
-		return output.append(String.valueOf(this.value));
-	}
-	return super.printExpression(indent, output);
-}
-
 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/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index f7e6faf..f4ea79a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -9,6 +9,8 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Fraunhofer FIRST - extended API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
+ *     												and bug 292478 - Report potentially null across variable assignment
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
@@ -83,6 +85,9 @@
 	if (this.initialization == null) {
 		return flowInfo;
 	}
+	if ((this.initialization.implicitConversion & TypeIds.UNBOXING) != 0) {
+		this.initialization.checkNPE(currentScope, flowContext, flowInfo);
+	}
 	int nullStatus = this.initialization.nullStatus(flowInfo);
 	flowInfo =
 		this.initialization
@@ -95,16 +100,7 @@
 	}
 	flowInfo.markAsDefinitelyAssigned(this.binding);
 	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
-		switch(nullStatus) {
-			case FlowInfo.NULL :
-				flowInfo.markAsDefinitelyNull(this.binding);
-				break;
-			case FlowInfo.NON_NULL :
-				flowInfo.markAsDefinitelyNonNull(this.binding);
-				break;
-			default:
-				flowInfo.markAsDefinitelyUnknown(this.binding);
-		}
+		flowInfo.markNullStatus(this.binding, nullStatus);
 		// no need to inform enclosing try block since its locals won't get
 		// known by the finally block
 	}
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 e9b1788..2fbb5de 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
@@ -9,6 +9,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nick Teryaev - fix for bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=40752)
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -149,6 +150,9 @@
 	if (this.arguments != null) {
 		int length = this.arguments.length;
 		for (int i = 0; i < length; i++) {
+			if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
+				this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
+			}
 			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
 		}
 	}
@@ -1075,6 +1079,9 @@
 public void setFieldIndex(int depth) {
 	// ignore for here
 }
+public TypeBinding expectedType() {
+	return this.expectedType;
+}
 
 public void traverse(ASTVisitor visitor, BlockScope blockScope) {
 	if (visitor.visit(this, blockScope)) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
index 4076d51..c041fee 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -62,6 +63,12 @@
 			}
 		}
 		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
+		if ((this.left.implicitConversion & TypeIds.UNBOXING) != 0) {
+			this.left.checkNPE(currentScope, flowContext, flowInfo);
+		}
+		if ((this.right.implicitConversion & TypeIds.UNBOXING) != 0) {
+			this.right.checkNPE(currentScope, flowContext, flowInfo);
+		}
 		// The definitely null variables in right info when true should not be missed out while merging
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=299900
 		FlowInfo leftInfoWhenTrueForMerging = leftInfo.initsWhenTrue().unconditionalCopy().addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect());
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 d31d14d..48bea2c 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -141,6 +142,9 @@
 		if (this.arguments != null) {
 			for (int i = 0, count = this.arguments.length; i < count; i++) {
 				flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
+				if ((this.arguments[i].implicitConversion & TypeIds.UNBOXING) != 0) {
+					this.arguments[i].checkNPE(currentScope, flowContext, flowInfo);
+				}
 			}
 		}
 
@@ -301,6 +305,7 @@
 
 		this.constant = Constant.NotAConstant;
 		TypeBinding enclosingInstanceType = null;
+		ReferenceBinding enclosingInstanceReference = null;
 		TypeBinding receiverType = null;
 		boolean hasError = false;
 		boolean enclosingInstanceContainsCast = false;
@@ -329,6 +334,14 @@
 			} else if (this.type instanceof QualifiedTypeReference) {
 				scope.problemReporter().illegalUsageOfQualifiedTypeReference((QualifiedTypeReference)this.type);
 				hasError = true;
+			} else if (!(enclosingInstanceReference = (ReferenceBinding) enclosingInstanceType).canBeSeenBy(scope)) {
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=317212
+				enclosingInstanceType = new ProblemReferenceBinding(
+							enclosingInstanceReference.compoundName,
+							enclosingInstanceReference,
+							ProblemReasons.NotVisible);
+				scope.problemReporter().invalidType(this.enclosingInstance, enclosingInstanceType);
+				hasError = true;
 			} else {
 				receiverType = ((SingleTypeReference) this.type).resolveTypeEnclosing(scope, (ReferenceBinding) enclosingInstanceType);
 				if (receiverType != null && enclosingInstanceContainsCast) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
index 65651c5..4dd1e12 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java
@@ -129,7 +129,9 @@
 			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
 				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
 			}
-			checkNPE(currentScope, flowContext, flowInfo, true);
+			if (needValue) {
+				checkNPE(currentScope, flowContext, flowInfo, true);
+			}
 	}
 
 	if (needValue) {
@@ -226,12 +228,14 @@
 			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
 				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
 			}
-			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
+			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
 				localBinding.useFlag = LocalVariableBinding.USED;
 			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
 				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
 			}
-			checkNPE(currentScope, flowContext, flowInfo, true);
+			if (needValue) {
+				checkNPE(currentScope, flowContext, flowInfo, true);
+			}
 	}
 	if (needValue) {
 		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
@@ -250,7 +254,7 @@
 
 public void checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, boolean checkString) {
 	// cannot override localVariableBinding because this would project o.m onto o when
-	// analysing assignments
+	// analyzing assignments
 	if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
 		LocalVariableBinding local = (LocalVariableBinding) this.binding;
 		if (local != null &&
@@ -261,9 +265,15 @@
 					FlowContext.MAY_NULL, flowInfo);
 			}
 			flowInfo.markAsComparedEqualToNonNull(local);
-				// from thereon it is set
+			// from thereon it is set
+			if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+				flowInfo.markedAsNullOrNonNullInAssertExpression(local);
+			}
 			if (flowContext.initsOnFinally != null) {
 				flowContext.initsOnFinally.markAsComparedEqualToNonNull(local);
+				if ((flowContext.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) != 0) {
+					flowContext.initsOnFinally.markedAsNullOrNonNullInAssertExpression(local);
+				}
 			}
 		}
 	}
@@ -891,6 +901,10 @@
 	if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
 		LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding;
 		if (localVariableBinding != null) {
+			if ((localVariableBinding.tagBits & TagBits.NotInitialized) != 0) {
+				// local was tagged as uninitialized
+				return;
+			}
 			switch(localVariableBinding.useFlag) {
 				case LocalVariableBinding.FAKE_USED :
 				case LocalVariableBinding.USED :
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
index 7c8070f..54f5639 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java
@@ -29,7 +29,7 @@
  * @version $Id: Reference.java 23404 2010-02-03 14:10:22Z stephan $
  */
 public abstract class Reference extends Expression  {
-//{ObjectTeams: support expected type
+//{ObjectTeams: store expected type to support infering callout-to-field
 	public TypeBinding expectedType;
 	@Override
 	public void setExpectedType(TypeBinding expectedType) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 506025e..c3d2fc3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
@@ -42,6 +43,9 @@
 
 	if (this.expression != null) {
 		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
+		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
+			this.expression.checkNPE(currentScope, flowContext, flowInfo);
+		}
 	}
 	this.initStateIndex =
 		currentScope.methodScope().recordInitializationStates(flowInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 4662d66..877f2d5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 292478 - Report potentially null across variable assignment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -759,6 +760,10 @@
 	if ((this.bits & ASTNode.RestrictiveFlagMASK) == Binding.LOCAL) {
 		LocalVariableBinding localVariableBinding = (LocalVariableBinding) this.binding;
 		if (localVariableBinding != null) {
+			if ((localVariableBinding.tagBits & TagBits.NotInitialized) != 0) {
+				// local was tagged as uninitialized
+				return;
+			}
 			switch(localVariableBinding.useFlag) {
 				case LocalVariableBinding.FAKE_USED :
 				case LocalVariableBinding.USED :
@@ -818,13 +823,8 @@
 			return FlowInfo.UNKNOWN;
 		case Binding.LOCAL : // reading a local variable
 			LocalVariableBinding local = (LocalVariableBinding) this.binding;
-			if (local != null) {
-				if (flowInfo.isDefinitelyNull(local))
-					return FlowInfo.NULL;
-				if (flowInfo.isDefinitelyNonNull(local))
-					return FlowInfo.NON_NULL;
-				return FlowInfo.UNKNOWN;
-			}
+			if (local != null)
+				return flowInfo.nullStatus(local);
 	}
 	return FlowInfo.NON_NULL; // never get there
 }
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 a56af5b..629a336 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
@@ -236,4 +236,12 @@
 	resolve(scope);
 	return Constant.NotAConstant;
 }
+/** 
+ * Implementation of {@link org.eclipse.jdt.internal.compiler.lookup.InvocationSite#expectedType}
+ * suitable at this level. Subclasses should override as necessary.
+ * @see org.eclipse.jdt.internal.compiler.lookup.InvocationSite#expectedType()
+ */
+public TypeBinding expectedType() {
+	return null;
+}
 }
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 0d2e13f..6fbfe22 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, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -45,8 +46,11 @@
 	int mergedInitStateIndex = -1;
 
 	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
-	    try {
+		try {
 			flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
+			if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
+				this.expression.checkNPE(currentScope, flowContext, flowInfo);
+			}
 			SwitchFlowContext switchContext =
 				new SwitchFlowContext(flowContext, this, (this.breakLabel = new BranchLabel()));
 
@@ -94,8 +98,8 @@
 			}
 
 			final TypeBinding resolvedTypeBinding = this.expression.resolvedType;
-			if (this.caseCount > 0 && resolvedTypeBinding.isEnum()) {
-				final SourceTypeBinding sourceTypeBinding = this.scope.classScope().referenceContext.binding;
+			if (resolvedTypeBinding.isEnum()) {
+				final SourceTypeBinding sourceTypeBinding = currentScope.classScope().referenceContext.binding;
 				this.synthetic = sourceTypeBinding.addSyntheticMethodForSwitchEnum(resolvedTypeBinding);
 			}
 			// if no default case, then record it may jump over the block directly to the end
@@ -111,9 +115,9 @@
 			this.mergedInitStateIndex =
 				currentScope.methodScope().recordInitializationStates(mergedInfo);
 			return mergedInfo;
-	    } finally {
-	        if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
-	    }
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
 	}
 
 	/**
@@ -124,7 +128,7 @@
 	 */
 	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
 
-	    try {
+		try {
 			if ((this.bits & IsReachable) == 0) {
 				return;
 			}
@@ -133,36 +137,37 @@
 			// prepare the labels and constants
 			this.breakLabel.initialize(codeStream);
 			CaseLabel[] caseLabels = new CaseLabel[this.caseCount];
-			boolean needSwitch = this.caseCount != 0;
-			for (int i = 0; i < this.caseCount; i++) {
+			for (int i = 0, max = this.caseCount; i < max; i++) {
 				this.cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream));
 				caseLabels[i].tagBits |= BranchLabel.USED;
 			}
 			CaseLabel defaultLabel = new CaseLabel(codeStream);
-			if (needSwitch) defaultLabel.tagBits |= BranchLabel.USED;
+			final boolean hasCases = this.caseCount != 0;
+			if (hasCases) defaultLabel.tagBits |= BranchLabel.USED;
 			if (this.defaultCase != null) {
 				this.defaultCase.targetLabel = defaultLabel;
 			}
 
 			final TypeBinding resolvedType = this.expression.resolvedType;
+			boolean valueRequired = false;
 			if (resolvedType.isEnum()) {
-				if (needSwitch) {
-					// go through the translation table
-					codeStream.invoke(Opcodes.OPC_invokestatic, this.synthetic, null /* default declaringClass */);
-					this.expression.generateCode(currentScope, codeStream, true);
-					// get enum constant ordinal()
-					codeStream.invokeEnumOrdinal(resolvedType.constantPoolName());
-					codeStream.iaload();
-				} else {
-					// no need to go through the translation table
-					this.expression.generateCode(currentScope, codeStream, false);
+				// go through the translation table
+				codeStream.invoke(Opcodes.OPC_invokestatic, this.synthetic, null /* default declaringClass */);
+				this.expression.generateCode(currentScope, codeStream, true);
+				// get enum constant ordinal()
+				codeStream.invokeEnumOrdinal(resolvedType.constantPoolName());
+				codeStream.iaload();
+				if (!hasCases) {
+					// we can get rid of the generated ordinal value
+					codeStream.pop();
 				}
 			} else {
+				valueRequired = this.expression.constant == Constant.NotAConstant || hasCases;
 				// generate expression
-				this.expression.generateCode(currentScope, codeStream, needSwitch); // value required (switch without cases)
+				this.expression.generateCode(currentScope, codeStream, valueRequired);
 			}
 			// generate the appropriate switch table/lookup bytecode
-			if (needSwitch) {
+			if (hasCases) {
 				int[] sortedIndexes = new int[this.caseCount];
 				// we sort the keys to be able to generate the code for tableswitch or lookupswitch
 				for (int i = 0; i < this.caseCount; i++) {
@@ -194,6 +199,8 @@
 					codeStream.lookupswitch(defaultLabel, this.constants, sortedIndexes, caseLabels);
 				}
 				codeStream.updateLastRecordedEndPC(this.scope, codeStream.position);
+			} else if (valueRequired) {
+				codeStream.pop();
 			}
 
 			// generate the switch block statements
@@ -234,9 +241,9 @@
 				defaultLabel.place();
 			}
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
-	    } finally {
-	        if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
-	    }
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
 	}
 
 	public StringBuffer printStatement(int indent, StringBuffer output) {
@@ -258,8 +265,7 @@
 	}
 
 	public void resolve(BlockScope upperScope) {
-
-	    try {
+		try {
 			boolean isEnumSwitch = false;
 			TypeBinding expressionType = this.expression.resolveType(upperScope);
 			if (expressionType != null) {
@@ -285,7 +291,7 @@
 				}
 			}
 			if (this.statements != null) {
-				this.scope = /*explicitDeclarations == 0 ? upperScope : */new BlockScope(upperScope);
+				this.scope = new BlockScope(upperScope);
 				int length;
 				// collection of cases is too big but we will only iterate until caseCount
 				this.cases = new CaseStatement[length = this.statements.length];
@@ -355,9 +361,9 @@
 					}
 				}
 			}
-	    } finally {
-	        if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
-	    }
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
 	}
 
 	public void traverse(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index c727175..77e762c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -1909,6 +1909,28 @@
 			ReferenceBinding existingType = (ReferenceBinding) existing;
 			if (existingType instanceof TypeVariableBinding) {
 				blockScope.problemReporter().typeHiding(this, (TypeVariableBinding) existingType);
+				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=312989, check for collision with enclosing type.
+				Scope outerScope = blockScope.parent;
+checkOuterScope:while (outerScope != null) {
+					Binding existing2 = outerScope.getType(this.name);
+					if (existing2 instanceof TypeVariableBinding && existing2.isValidBinding()) {
+						TypeVariableBinding tvb = (TypeVariableBinding) existingType;
+						Binding declaringElement = tvb.declaringElement;
+						if (declaringElement instanceof ReferenceBinding
+								&& CharOperation.equals(((ReferenceBinding) declaringElement).sourceName(), this.name)) {
+							blockScope.problemReporter().typeCollidesWithEnclosingType(this);
+							break checkOuterScope;
+						}
+					} else if (existing2 instanceof ReferenceBinding
+							&& existing2.isValidBinding()
+							&& outerScope.isDefinedInType((ReferenceBinding) existing2)) { 
+							blockScope.problemReporter().typeCollidesWithEnclosingType(this);
+							break checkOuterScope;
+					} else if (existing2 == null) {
+						break checkOuterScope;
+					}
+					outerScope = outerScope.parent;
+				}
 			} else if (existingType instanceof LocalTypeBinding
 						&& ((LocalTypeBinding) existingType).scope.methodScope() == blockScope.methodScope()) {
 					// dup in same method
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
index 00db5c9..144e64e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - Contribution for bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -63,6 +64,9 @@
 					new LoopingFlowContext(flowContext, flowInfo, this, null,
 						null, currentScope)),
 				condInfo);
+		if ((this.condition.implicitConversion & TypeIds.UNBOXING) != 0) {
+			this.condition.checkNPE(currentScope, flowContext, flowInfo);
+		}
 
 		LoopingFlowContext loopingContext;
 		FlowInfo actionInfo;
@@ -137,6 +141,13 @@
 						actionInfo.unconditionalInits()).
 					addInitializationsFrom(condInfo.initsWhenFalse());
 			}
+			if (loopingContext.hasEscapingExceptions()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926
+				FlowInfo loopbackFlowInfo = flowInfo.copy();
+				if (this.continueLabel != null) {  // we do get to the bottom 
+					loopbackFlowInfo.mergedWith(actionInfo.unconditionalCopy());
+				}
+				loopingContext.simulateThrowAfterLoopBack(loopbackFlowInfo);
+			}
 		}
 
 		// end of loop
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 109bc66..13f27ee 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, 2009 BEA Systems, Inc.
+ * Copyright (c) 2005, 2010 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
@@ -7,15 +7,19 @@
  *
  * Contributors:
  *    tyeung@bea.com - initial API and implementation
+ *    olivier_thomann@ca.ibm.com - add hashCode() and equals(..) methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.classfmt;
 
+import java.util.Arrays;
+
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
 import org.eclipse.jdt.internal.compiler.env.*;
 import org.eclipse.jdt.internal.compiler.impl.*;
 import org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.eclipse.jdt.internal.compiler.util.Util;
 
 public class AnnotationInfo extends ClassFileStruct implements IBinaryAnnotation {
 	/** The name of the annotation type */
@@ -376,4 +380,30 @@
 	}
 	return buffer.toString();
 }
+public int hashCode() {
+	final int prime = 31;
+	int result = 1;
+	result = prime * result + Util.hashCode(this.pairs);
+	result = prime * result + CharOperation.hashCode(this.typename);
+	return result;
+}
+public boolean equals(Object obj) {
+	if (this == obj) {
+		return true;
+	}
+	if (obj == null) {
+		return false;
+	}
+	if (getClass() != obj.getClass()) {
+		return false;
+	}
+	AnnotationInfo other = (AnnotationInfo) obj;
+	if (!Arrays.equals(this.pairs, other.pairs)) {
+		return false;
+	}
+	if (!Arrays.equals(this.typename, other.typename)) {
+		return false;
+	}
+	return true;
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
index 3c81e19..3a9e163 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -1153,8 +1153,27 @@
 		for (int j = 0; j < currentPairsLength; j++) {
 			if (!CharOperation.equals(currentPairs[j].getName(), otherPairs[j].getName()))
 				return true;
-			if (!currentPairs[j].getValue().equals(otherPairs[j].getValue()))
+			final Object value = currentPairs[j].getValue();
+			final Object value2 = otherPairs[j].getValue();
+			if (value instanceof Object[]) {
+				Object[] currentValues = (Object[]) value;
+				if (value2 instanceof Object[]) {
+					Object[] currentValues2 = (Object[]) value2;
+					final int length = currentValues.length;
+					if (length != currentValues2.length) {
+						return true;
+					}
+					for (int n = 0; n < length; n++) {
+						if (!currentValues[n].equals(currentValues2[n])) {
+							return true;
+						}
+					}
+					return false;
+				}
 				return true;
+			} else if (!value.equals(value2)) {
+				return true;
+			}
 		}
 	}
 	return false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.java
index 188051b..5a40c0d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2007 BEA Systems, Inc.
+ * Copyright (c) 2005, 2010 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
@@ -7,9 +7,14 @@
  *
  * Contributors:
  *    tyeung@bea.com - initial API and implementation
+ *    olivier_thomann@ca.ibm.com - add hashCode() and equals(..) methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.classfmt;
 
+import java.util.Arrays;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
 public class ElementValuePairInfo implements org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair {
 
 	static final ElementValuePairInfo[] NoMembers = new ElementValuePairInfo[0];
@@ -45,4 +50,34 @@
 	}
 	return buffer.toString();
 }
+public int hashCode() {
+	final int prime = 31;
+	int result = 1;
+	result = prime * result + CharOperation.hashCode(this.name);
+	result = prime * result + ((this.value == null) ? 0 : this.value.hashCode());
+	return result;
+}
+public boolean equals(Object obj) {
+	if (this == obj) {
+		return true;
+	}
+	if (obj == null) {
+		return false;
+	}
+	if (getClass() != obj.getClass()) {
+		return false;
+	}
+	ElementValuePairInfo other = (ElementValuePairInfo) obj;
+	if (!Arrays.equals(this.name, other.name)) {
+		return false;
+	}
+	if (this.value == null) {
+		if (other.value != null) {
+			return false;
+		}
+	} else if (!this.value.equals(other.value)) {
+		return false;
+	}
+	return true;
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ClassSignature.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ClassSignature.java
index 6c68a09..f3e4685 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ClassSignature.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/ClassSignature.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2007 BEA Systems, Inc.
+ * Copyright (c) 2005, 2010 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
@@ -7,9 +7,14 @@
  *
  * Contributors:
  *    tyeung@bea.com - initial API and implementation
+ *    olivier_thomann@ca.ibm.com - add hashCode() and equals(..) methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.env;
 
+import java.util.Arrays;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+
 /**
  * Represents a class reference in the class file.
  * One of the possible results for the default value of an annotation method or an element value pair.
@@ -35,4 +40,25 @@
 	buffer.append(".class"); //$NON-NLS-1$
 	return buffer.toString();
 }
+
+public int hashCode() {
+	final int prime = 31;
+	int result = 1;
+	result = prime * result + CharOperation.hashCode(this.className);
+	return result;
+}
+
+public boolean equals(Object obj) {
+	if (this == obj) {
+		return true;
+	}
+	if (obj == null) {
+		return false;
+	}
+	if (getClass() != obj.getClass()) {
+		return false;
+	}
+	ClassSignature other = (ClassSignature) obj;
+	return Arrays.equals(this.className, other.className);
+}
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.java
index 66a8434..437df94 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2007 BEA Systems, Inc.
+ * Copyright (c) 2005, 2010 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
@@ -7,9 +7,13 @@
  *
  * Contributors:
  *    tyeung@bea.com - initial API and implementation
+ *    olivier_thomann@ca.ibm.com - add hashCode() and equals(..) methods
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.env;
 
+import java.util.Arrays;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
 /**
  * Represents a reference to a enum constant in the class file.
  * One of the possible results for the default value of an annotation method.
@@ -45,4 +49,29 @@
 	buffer.append(this.constName);
 	return buffer.toString();
 }
+
+public int hashCode() {
+	final int prime = 31;
+	int result = 1;
+	result = prime * result + CharOperation.hashCode(this.constName);
+	result = prime * result + CharOperation.hashCode(this.typeName);
+	return result;
+}
+
+public boolean equals(Object obj) {
+	if (this == obj) {
+		return true;
+	}
+	if (obj == null) {
+		return false;
+	}
+	if (getClass() != obj.getClass()) {
+		return false;
+	}
+	EnumConstantSignature other = (EnumConstantSignature) obj;
+	if (!Arrays.equals(this.constName, other.constName)) {
+		return false;
+	}
+	return Arrays.equals(this.typeName, other.typeName);
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
index 3470fa7..bb0e2a6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java
@@ -157,11 +157,31 @@
 	this.initsWhenFalse.markAsDefinitelyNull(local);
 }
 
+public void resetNullInfo(LocalVariableBinding local) {
+	this.initsWhenTrue.resetNullInfo(local);
+	this.initsWhenFalse.resetNullInfo(local);
+}
+
+public void markPotentiallyNullBit(LocalVariableBinding local) {
+	this.initsWhenTrue.markPotentiallyNullBit(local);
+	this.initsWhenFalse.markPotentiallyNullBit(local);
+}
+
+public void markPotentiallyNonNullBit(LocalVariableBinding local) {
+	this.initsWhenTrue.markPotentiallyNonNullBit(local);
+	this.initsWhenFalse.markPotentiallyNonNullBit(local);
+}
+
 public void markAsDefinitelyUnknown(LocalVariableBinding local) {
 	this.initsWhenTrue.markAsDefinitelyUnknown(local);
 	this.initsWhenFalse.markAsDefinitelyUnknown(local);
 }
 
+public void markPotentiallyUnknownBit(LocalVariableBinding local) {
+	this.initsWhenTrue.markPotentiallyUnknownBit(local);
+	this.initsWhenFalse.markPotentiallyUnknownBit(local);
+}
+
 public FlowInfo setReachMode(int reachMode) {
 	if (reachMode == REACHABLE) {
 		this.tagBits &= ~UNREACHABLE;
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 7e04211..369d24e 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
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
+import java.util.ArrayList;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
@@ -92,6 +93,7 @@
 	// all related catch blocks are marked as reachable... instead of those only
 	// until the point where it is safely handled (Smarter - see comment at the end)
 	FlowContext traversedContext = this;
+	ArrayList abruptlyExitedLoops = null;
 	while (traversedContext != null) {
 		SubRoutineStatement sub;
 		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
@@ -115,6 +117,12 @@
 				    int state = caughtException == null
 				    	? Scope.EQUAL_OR_MORE_SPECIFIC /* any exception */
 				        : Scope.compareTypes(raisedException, caughtException);
+				    if (abruptlyExitedLoops != null && caughtException != null && state != Scope.NOT_RELATED) {
+				    	for (int i = 0, abruptlyExitedLoopsCount = abruptlyExitedLoops.size(); i < abruptlyExitedLoopsCount; i++) {
+							LoopingFlowContext loop = (LoopingFlowContext) abruptlyExitedLoops.get(i);
+							loop.recordCatchContextOfEscapingException(exceptionContext, caughtException);
+						}
+					}
 					switch (state) {
 						case Scope.EQUAL_OR_MORE_SPECIFIC :
 							exceptionContext.recordHandlingException(
@@ -156,6 +164,11 @@
 				}
 				break; // not handled anywhere, thus jump to error handling
 			}
+		} else if (traversedContext instanceof LoopingFlowContext) {
+			if (abruptlyExitedLoops == null) {
+				abruptlyExitedLoops = new ArrayList(5);
+			}
+			abruptlyExitedLoops.add(traversedContext);
 		}
 
 		traversedContext.recordReturnFrom(flowInfo.unconditionalInits());
@@ -195,6 +208,7 @@
 		raisedCount);
 	FlowContext traversedContext = this;
 
+	ArrayList abruptlyExitedLoops = null;
 	while (traversedContext != null) {
 		SubRoutineStatement sub;
 		if (((sub = traversedContext.subroutine()) != null) && sub.isSubRoutineEscaping()) {
@@ -220,6 +234,12 @@
 						    int state = caughtException == null
 						    	? Scope.EQUAL_OR_MORE_SPECIFIC /* any exception */
 						        : Scope.compareTypes(raisedException, caughtException);
+						    if (abruptlyExitedLoops != null && caughtException != null && state != Scope.NOT_RELATED) {
+						    	for (int i = 0, abruptlyExitedLoopsCount = abruptlyExitedLoops.size(); i < abruptlyExitedLoopsCount; i++) {
+									LoopingFlowContext loop = (LoopingFlowContext) abruptlyExitedLoops.get(i);
+									loop.recordCatchContextOfEscapingException(exceptionContext, caughtException);
+								}
+							}
 							switch (state) {
 								case Scope.EQUAL_OR_MORE_SPECIFIC :
 									exceptionContext.recordHandlingException(
@@ -282,6 +302,11 @@
 				}
 				break; // not handled anywhere, thus jump to error handling
 			}
+        } else if (traversedContext instanceof LoopingFlowContext) {
+			if (abruptlyExitedLoops == null) {
+				abruptlyExitedLoops = new ArrayList(5);
+			}
+			abruptlyExitedLoops.add(traversedContext);
 		}
 		if (remainingCount == 0)
 			return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
index 4a1005d..0f5b818 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java
@@ -8,11 +8,14 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 292478 - Report potentially null across variable assignment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.IfStatement;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
 import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallTrackingVariable;
@@ -34,9 +37,12 @@
 	public final static int UNREACHABLE = 1;
 	public final static int NULL_FLAG_MASK = 2;
 
-	public final static int UNKNOWN = 0;
-	public final static int NULL = 1;
-	public final static int NON_NULL = -1;
+	public final static int UNKNOWN = 1;
+	public final static int NULL = 2;
+	public final static int NON_NULL = 4;
+	public final static int POTENTIALLY_UNKNOWN = 8;
+	public final static int POTENTIALLY_NULL = 16;
+	public final static int POTENTIALLY_NON_NULL = 32;
 
 	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
 	static {
@@ -260,6 +266,26 @@
 	abstract public void markAsDefinitelyNull(LocalVariableBinding local);
 
 	/**
+	 * Reset all null-information about a given local.
+	 */
+	abstract public void resetNullInfo(LocalVariableBinding local);
+
+	/**
+	 * Record a local may have got assigned to unknown (set the bit on existing info).
+	 */
+	abstract public void markPotentiallyUnknownBit(LocalVariableBinding local);
+
+	/**
+	 * Record a local may have got assigned to null (set the bit on existing info).
+	 */
+	abstract public void markPotentiallyNullBit(LocalVariableBinding local);
+
+	/**
+	 * Record a local may have got assigned to non-null (set the bit on existing info).
+	 */
+	abstract public void markPotentiallyNonNullBit(LocalVariableBinding local);
+
+	/**
 	 * Record a local got definitely assigned.
 	 */
 	abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
@@ -270,6 +296,61 @@
 abstract public void markAsDefinitelyUnknown(LocalVariableBinding local);
 
 /**
+ * Mark the null status of the given local according to the given status
+ * @param local
+ * @param nullStatus bitset of FLowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
+ */
+public void markNullStatus(LocalVariableBinding local, int nullStatus) {
+	switch(nullStatus) {
+		// definite status?
+		case FlowInfo.UNKNOWN :
+			markAsDefinitelyUnknown(local);
+			break;
+		case FlowInfo.NULL :
+			markAsDefinitelyNull(local);
+			break;
+		case FlowInfo.NON_NULL :
+			markAsDefinitelyNonNull(local);
+			break;
+		default:
+			// collect potential status:
+			resetNullInfo(local);
+			if ((nullStatus & FlowInfo.POTENTIALLY_UNKNOWN) != 0)
+				markPotentiallyUnknownBit(local);
+			if ((nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
+				markPotentiallyNullBit(local);
+			if ((nullStatus & FlowInfo.POTENTIALLY_NON_NULL) != 0)
+				markPotentiallyNonNullBit(local);
+			if ((nullStatus & (FlowInfo.POTENTIALLY_NULL|FlowInfo.POTENTIALLY_NON_NULL|FlowInfo.POTENTIALLY_UNKNOWN)) == 0)
+				markAsDefinitelyUnknown(local);
+	}
+}
+
+/**
+ * Answer the null status of the given local
+ * @param local
+ * @return bitset of FlowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
+ */
+public int nullStatus(LocalVariableBinding local) {
+	if (isDefinitelyUnknown(local))
+		return FlowInfo.UNKNOWN;
+	if (isDefinitelyNull(local))
+		return FlowInfo.NULL;
+	if (isDefinitelyNonNull(local))
+		return FlowInfo.NON_NULL;
+	int status = 0;
+	if (isPotentiallyUnknown(local))
+		status |= FlowInfo.POTENTIALLY_UNKNOWN;
+	if (isPotentiallyNull(local))
+		status |= FlowInfo.POTENTIALLY_NULL;
+	if (isPotentiallyNonNull(local))
+		status |= FlowInfo.POTENTIALLY_NON_NULL;
+	if (status > 0)
+		return status;
+	return FlowInfo.UNKNOWN;
+}
+
+/**
  * Merge branches using optimized boolean conditions
  */
 public static UnconditionalFlowInfo mergedOptimizedBranches(
@@ -314,7 +395,7 @@
 public static UnconditionalFlowInfo mergedOptimizedBranchesIfElse(
 		FlowInfo initsWhenTrue, boolean isOptimizedTrue,
 		FlowInfo initsWhenFalse, boolean isOptimizedFalse,
-		boolean allowFakeDeadBranch, FlowInfo flowInfo) {
+		boolean allowFakeDeadBranch, FlowInfo flowInfo, IfStatement ifStatement) {
 	UnconditionalFlowInfo mergedInfo;
 	if (isOptimizedTrue){
 		if (initsWhenTrue == FlowInfo.DEAD_END && allowFakeDeadBranch) {
@@ -341,7 +422,7 @@
 		}
 	}
 	else if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 &&
-				(initsWhenFalse.tagBits & FlowInfo.UNREACHABLE) != 0 &&
+				(ifStatement.bits & ASTNode.IsElseStatementUnreachable) != 0 &&
 				initsWhenTrue != FlowInfo.DEAD_END &&
 				initsWhenFalse != FlowInfo.DEAD_END) {
 		// Done when the then branch will always be executed but the condition does not have a boolean
@@ -358,7 +439,7 @@
 		
 	}
 	else if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 &&
-			(initsWhenTrue.tagBits & FlowInfo.UNREACHABLE) != 0 && initsWhenTrue != FlowInfo.DEAD_END
+			(ifStatement.bits & ASTNode.IsThenStatementUnreachable) != 0 && initsWhenTrue != FlowInfo.DEAD_END
 			&& initsWhenFalse != FlowInfo.DEAD_END) {
 		// Done when the else branch will always be executed but the condition does not have a boolean
 		// true or false (i.e if(true), etc) for sure
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 8b02bc7..69fe575 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
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.flow;
 
+import java.util.ArrayList;
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.Reference;
@@ -17,6 +18,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
@@ -45,6 +47,23 @@
 	int[] nullCheckTypes;
 	int nullCount;
 
+	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926
+	static private class EscapingExceptionCatchSite {
+		final ReferenceBinding caughtException;
+		final ExceptionHandlingFlowContext catchingContext;
+		public EscapingExceptionCatchSite(ExceptionHandlingFlowContext catchingContext,	ReferenceBinding caughtException) {
+			this.catchingContext = catchingContext;
+			this.caughtException = caughtException;
+		}
+		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.
+					);
+		}
+	}
+	private ArrayList escapingExceptionCatchSites = null;
+
 	Scope associatedScope;
 
 	public LoopingFlowContext(
@@ -608,4 +627,31 @@
 			}
 		}
 	}
+
+	/* Simulate a throw of an exception from inside a loop in its second or subsequent iteration.
+	   See https://bugs.eclipse.org/bugs/show_bug.cgi?id=321926
+	 */
+	public void simulateThrowAfterLoopBack(FlowInfo flowInfo) {
+		if (this.escapingExceptionCatchSites != null) {
+			for (int i = 0, exceptionCount = this.escapingExceptionCatchSites.size(); i < exceptionCount; i++) {
+				((EscapingExceptionCatchSite) this.escapingExceptionCatchSites.get(i)).simulateThrowAfterLoopBack(flowInfo);
+			}
+			this.escapingExceptionCatchSites = null; // don't care for it anymore.
+		}
+	}
+
+	/* Record the fact that some exception thrown by code within this loop
+	   is caught by an outer catch block. This is used to propagate data flow
+	   along the edge back to the next iteration. See simulateThrowAfterLoopBack
+	 */
+	public void recordCatchContextOfEscapingException(ExceptionHandlingFlowContext catchingContext,	ReferenceBinding caughtException) {
+		if (this.escapingExceptionCatchSites == null) {
+			this.escapingExceptionCatchSites = new ArrayList(5);
+		}
+		this.escapingExceptionCatchSites.add(new EscapingExceptionCatchSite(catchingContext, caughtException));
+	}
+
+	public boolean hasEscapingExceptions() {
+		return this.escapingExceptionCatchSites != null;
+	}
 }